This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
C++ PATCH for memory corruption
- To: egcs-patches at egcs dot cygnus dot com
- Subject: C++ PATCH for memory corruption
- From: mark at codesourcery dot com
- Date: Tue, 15 Jun 1999 16:49:00 -0700
- Organization: CodeSourcery, LLC
The following patch fixes a bug on code like:
template <class T>
struct S1 {
S1 (T = T (0));
};
template <class T>
inline void f () {
S1<T> s;
S1<T*> s2;
}
struct S2 {
void g();
};
void g()
{
f<int>();
}
void S2::g () {}
Here, we would (upon instantiation of `f'), push to the top-level
saving away the cached `previous_class_values' for `S2'. Then, we'd
free the obstack containing them when instantiating the objects
declared inside `f'.
Installed on the mainline and on the branch.
--
Mark Mitchell mark@codesourcery.com
CodeSourcery, LLC http://www.codesourcery.com
1999-06-15 Mark Mitchell <mark@codesourcery.com>
* cp-tree.h (class_cache_firstobj): Declare.
(maybe_push_cache_obstack): Rename to push_cache_obstack.
* class.c (permanent_obstack): Remove declaration.
(class_cache_firstobj): Make it global.
(add_method): Don't use permanent_obstack directly.
(pushclass): Only free the class_cache_obstack if we know how far
back to free it.
(maybe_push_cache_obstack): Rename to push_cache_obstack.
* decl.c: Remove dead comment.
(saved_scope): Add class_cache_firstobj.
(push_to_top_level): Save it.
(pop_from_top_level): Restore it.
(push_class_level_binding): Use push_cache_obstack, not
maybe_push_cache_obstack.
* search.c (push_class_decls): Likewise.
Index: cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.237
diff -u -p -r1.237 cp-tree.h
--- cp-tree.h 1999/05/25 15:31:27 1.237
+++ cp-tree.h 1999/06/15 23:00:14
@@ -2253,6 +2253,9 @@ extern int current_class_depth;
extern tree current_lang_name;
extern tree lang_name_cplusplus, lang_name_c, lang_name_java;
+/* The low-water mark on the class-cache obstack. */
+extern char *class_cache_firstobj;
+
/* Points to the name of that function. May not be the DECL_NAME
of CURRENT_FUNCTION_DECL due to overloading */
extern tree original_function_name;
@@ -2744,7 +2747,7 @@ extern void push_lang_context PROTO((t
extern void pop_lang_context PROTO((void));
extern tree instantiate_type PROTO((tree, tree, int));
extern void print_class_statistics PROTO((void));
-extern void maybe_push_cache_obstack PROTO((void));
+extern void push_cache_obstack PROTO((void));
extern unsigned HOST_WIDE_INT skip_rtti_stuff PROTO((tree *, tree));
extern void build_self_reference PROTO((void));
extern void warn_hidden PROTO((tree));
Index: class.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/class.c,v
retrieving revision 1.161
diff -u -p -r1.161 class.c
--- class.c 1999/06/03 07:16:10 1.161
+++ class.c 1999/06/15 23:00:11
@@ -36,8 +36,6 @@ Boston, MA 02111-1307, USA. */
#define obstack_chunk_alloc xmalloc
#define obstack_chunk_free free
-extern struct obstack permanent_obstack;
-
/* This is how we tell when two virtual member functions are really the
same. */
#define SAME_FN(FN1DECL, FN2DECL) (DECL_ASSEMBLER_NAME (FN1DECL) == DECL_ASSEMBLER_NAME (FN2DECL))
@@ -90,7 +88,7 @@ tree previous_class_values; /* TREE_LIST
static struct obstack class_cache_obstack;
/* The first object allocated on that obstack. We can use
obstack_free with tis value to free the entire obstack. */
-static char *class_cache_firstobj;
+char *class_cache_firstobj;
struct base_info;
@@ -1136,7 +1134,8 @@ void
add_method (type, fields, method)
tree type, *fields, method;
{
- push_obstacks (&permanent_obstack, &permanent_obstack);
+ push_obstacks_nochange ();
+ end_temporary_allocation ();
/* Setting the DECL_CONTEXT and DECL_CLASS_CONTEXT here is probably
redundant. */
@@ -4440,7 +4439,8 @@ pushclass (type, modify)
invalidate_class_lookup_cache ();
/* Now, free the obstack on which we cached all the values. */
- obstack_free (&class_cache_obstack, class_cache_firstobj);
+ if (class_cache_firstobj)
+ obstack_free (&class_cache_obstack, class_cache_firstobj);
class_cache_firstobj
= (char*) obstack_finish (&class_cache_obstack);
}
@@ -5197,7 +5197,7 @@ print_class_statistics ()
effect is undone by pop_obstacks. */
void
-maybe_push_cache_obstack ()
+push_cache_obstack ()
{
static int cache_obstack_initialized;
Index: decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.371
diff -u -p -r1.371 decl.c
--- decl.c 1999/06/05 11:03:52 1.371
+++ decl.c 1999/06/15 23:00:23
@@ -63,8 +63,6 @@ extern tree global_namespace;
extern void (*print_error_function) PROTO((char *));
extern int (*valid_lang_attribute) PROTO ((tree, tree, tree, tree));
-/* Stack of places to restore the search obstack back to. */
-
/* Obstack used for remembering local class declarations (like
enums and static (const) members. */
#include "stack.h"
@@ -2466,6 +2464,7 @@ struct saved_scope {
tree previous_class_type, previous_class_values;
int processing_specialization;
int processing_explicit_instantiation;
+ char *class_cache_firstobj;
};
static struct saved_scope *current_saved_scope;
@@ -2583,6 +2582,7 @@ maybe_push_to_top_level (pseudo)
s->processing_template_decl = processing_template_decl;
s->previous_class_type = previous_class_type;
s->previous_class_values = previous_class_values;
+ s->class_cache_firstobj = class_cache_firstobj;
s->processing_specialization = processing_specialization;
s->processing_explicit_instantiation = processing_explicit_instantiation;
@@ -2598,6 +2598,7 @@ maybe_push_to_top_level (pseudo)
shadowed_labels = NULL_TREE;
minimal_parse_mode = 0;
previous_class_type = previous_class_values = NULL_TREE;
+ class_cache_firstobj = 0;
processing_specialization = 0;
processing_explicit_instantiation = 0;
current_template_parms = NULL_TREE;
@@ -2669,6 +2670,7 @@ pop_from_top_level ()
previous_class_values = s->previous_class_values;
processing_specialization = s->processing_specialization;
processing_explicit_instantiation = s->processing_explicit_instantiation;
+ class_cache_firstobj = s->class_cache_firstobj;
free (s);
@@ -4471,7 +4473,7 @@ push_class_level_binding (name, x)
IDENTIFIER_CLASS_VALUE. */
if (push_class_binding (name, x))
{
- maybe_push_cache_obstack ();
+ push_cache_obstack ();
class_binding_level->class_shadowed
= tree_cons (name, IDENTIFIER_CLASS_VALUE (name),
class_binding_level->class_shadowed);
Index: search.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/search.c,v
retrieving revision 1.106
diff -u -p -r1.106 search.c
--- search.c 1999/06/07 13:28:06 1.106
+++ search.c 1999/06/15 23:00:25
@@ -2982,7 +2982,7 @@ push_class_decls (type)
/* Build up all the relevant bindings and such on the cache
obstack. That way no memory is wasted when we throw away the
cache later. */
- maybe_push_cache_obstack ();
+ push_cache_obstack ();
/* Enter type declarations and mark. */
dfs_walk (TYPE_BINFO (type), dfs_push_type_decls, unmarked_pushdecls_p, 0);
@@ -2990,7 +2990,7 @@ push_class_decls (type)
/* Enter non-type declarations and unmark. */
dfs_walk (TYPE_BINFO (type), dfs_push_decls, marked_pushdecls_p, 0);
- /* Undo the call to maybe_push_cache_obstack above. */
+ /* Undo the call to push_cache_obstack above. */
pop_obstacks ();
current_obstack = ambient_obstack;