From 66bc87dbe1928c819d5bfcfd2562dda954237c54 Mon Sep 17 00:00:00 2001 From: zack Date: Thu, 14 Nov 2002 21:58:38 +0000 Subject: [PATCH] * tree.c (tree_vec_elt_check_failed): New function. * tree.h (TREE_VEC_ELT_CHECK): New checking macro. (TREE_VEC_ELT): Use it. * tree-inline.c (optimize_inline_calls): Don't copy a zero-length vector. cp: * search.c (dfs_push_decls): Do not try to reorder elements 3..n of method_vec if method_vec has only two elements. Reverse order of two tests to avoid accessing unallocated memory. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@59114 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 9 +++++++++ gcc/cp/ChangeLog | 7 +++++++ gcc/cp/search.c | 5 +++-- gcc/tree-inline.c | 5 +++-- gcc/tree.c | 16 ++++++++++++++++ gcc/tree.h | 18 +++++++++++++++++- 6 files changed, 55 insertions(+), 5 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2fccc7e..ad002e1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2002-11-14 Zack Weinberg + + * tree.c (tree_vec_elt_check_failed): New function. + * tree.h (TREE_VEC_ELT_CHECK): New checking macro. + (TREE_VEC_ELT): Use it. + + * tree-inline.c (optimize_inline_calls): Don't copy a + zero-length vector. + 2002-11-14 Gabriel Dos Reis * diagnostic.c (sorry): Don't repeat "sorry, unimplemented" text. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 5550411..ad568b0 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2002-11-14 Zack Weinberg + + * search.c (dfs_push_decls): Do not try to reorder elements + 3..n of method_vec if method_vec has only two elements. + Reverse order of two tests to avoid accessing unallocated + memory. + 2002-11-14 Mark Mitchell * class.c (dfs_find_final_overrider): Adjust so that the most diff --git a/gcc/cp/search.c b/gcc/cp/search.c index c14287b..a4025ac 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -2544,7 +2544,8 @@ dfs_push_decls (binfo, data) method_vec = (CLASS_TYPE_P (type) ? CLASSTYPE_METHOD_VEC (type) : NULL_TREE); - if (method_vec) + + if (method_vec && TREE_VEC_LENGTH (method_vec) >= 3) { tree *methods; tree *end; @@ -2553,7 +2554,7 @@ dfs_push_decls (binfo, data) end = TREE_VEC_END (method_vec); for (methods = &TREE_VEC_ELT (method_vec, 2); - *methods && methods != end; + methods < end && *methods; methods++) setup_class_bindings (DECL_NAME (OVL_CURRENT (*methods)), /*type_binding_p=*/0); diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 898dacb..362ddd1 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -1367,8 +1367,9 @@ optimize_inline_calls (fn) { tree ifn = make_tree_vec (VARRAY_ACTIVE_SIZE (id.inlined_fns)); - memcpy (&TREE_VEC_ELT (ifn, 0), &VARRAY_TREE (id.inlined_fns, 0), - VARRAY_ACTIVE_SIZE (id.inlined_fns) * sizeof (tree)); + if (VARRAY_ACTIVE_SIZE (id.inlined_fns)) + memcpy (&TREE_VEC_ELT (ifn, 0), &VARRAY_TREE (id.inlined_fns, 0), + VARRAY_ACTIVE_SIZE (id.inlined_fns) * sizeof (tree)); DECL_INLINED_FNS (fn) = ifn; } } diff --git a/gcc/tree.c b/gcc/tree.c index a70b1b2..1bac17c 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -4665,6 +4665,22 @@ tree_class_check_failed (node, cl, file, line, function) tree_code_name[TREE_CODE (node)], function, trim_filename (file), line); } +/* Similar to above, except that the check is for the bounds of a TREE_VEC's + (dynamically sized) vector. */ + +void +tree_vec_elt_check_failed (idx, len, file, line, function) + int idx; + int len; + const char *file; + int line; + const char *function; +{ + internal_error + ("tree check: accessed elt %d of tree_vec with %d elts in %s, at %s:%d", + idx + 1, len, function, trim_filename (file), line); +} + #endif /* ENABLE_TREE_CHECKING */ /* For a new vector type node T, build the information necessary for diff --git a/gcc/tree.h b/gcc/tree.h index 2517dd2..8e8b168 100644 --- a/gcc/tree.h +++ b/gcc/tree.h @@ -317,12 +317,26 @@ struct tree_common GTY(()) __FUNCTION__); \ __t; }) +#define TREE_VEC_ELT_CHECK(t, i) __extension__ \ +(*({const tree __t = t; \ + const int __i = (i); \ + if (TREE_CODE (__t) != TREE_VEC) \ + tree_check_failed (__t, TREE_VEC, \ + __FILE__, __LINE__, __FUNCTION__); \ + if (__i < 0 || __i >= __t->vec.length) \ + tree_vec_elt_check_failed (__i, __t->vec.length, \ + __FILE__, __LINE__, __FUNCTION__); \ + &__t->vec.a[__i]; })) + extern void tree_check_failed PARAMS ((const tree, enum tree_code, const char *, int, const char *)) ATTRIBUTE_NORETURN; extern void tree_class_check_failed PARAMS ((const tree, int, const char *, int, const char *)) ATTRIBUTE_NORETURN; +extern void tree_vec_elt_check_failed PARAMS ((int, int, const char *, + int, const char *)) + ATTRIBUTE_NORETURN; #else /* not ENABLE_TREE_CHECKING, or not gcc */ @@ -330,6 +344,7 @@ extern void tree_class_check_failed PARAMS ((const tree, int, #define TREE_CLASS_CHECK(t, code) (t) #define CST_OR_CONSTRUCTOR_CHECK(t) (t) #define EXPR_CHECK(t) (t) +#define TREE_VEC_ELT_CHECK(t, i) ((t)->vec.a[i]) #endif @@ -810,10 +825,11 @@ struct tree_list GTY(()) /* In a TREE_VEC node. */ #define TREE_VEC_LENGTH(NODE) (TREE_VEC_CHECK (NODE)->vec.length) -#define TREE_VEC_ELT(NODE,I) (TREE_VEC_CHECK (NODE)->vec.a[I]) #define TREE_VEC_END(NODE) \ ((void) TREE_VEC_CHECK (NODE), &((NODE)->vec.a[(NODE)->vec.length])) +#define TREE_VEC_ELT(NODE,I) TREE_VEC_ELT_CHECK (NODE, I) + struct tree_vec GTY(()) { struct tree_common common; -- 2.7.4