summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2002-11-14 21:58:38 +0000
committerzack <zack@138bc75d-0d04-0410-961f-82ee72b054a4>2002-11-14 21:58:38 +0000
commit66bc87dbe1928c819d5bfcfd2562dda954237c54 (patch)
tree30bf88ca9d454be99af8fdef0fb816fd40bdf399
parent93f460bc2a78d455b9ce9ac0aab8aafcf41eddac (diff)
downloadgcc-66bc87dbe1928c819d5bfcfd2562dda954237c54.tar.gz
* 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
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/search.c5
-rw-r--r--gcc/tree-inline.c5
-rw-r--r--gcc/tree.c16
-rw-r--r--gcc/tree.h18
6 files changed, 55 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 2fccc7e80f6..ad002e1d05e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,12 @@
+2002-11-14 Zack Weinberg <zack@codesourcery.com>
+
+ * 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 <gdr@integrable-solutions.net>
* diagnostic.c (sorry): Don't repeat "sorry, unimplemented" text.
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 5550411c1bc..ad568b0d44e 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2002-11-14 Zack Weinberg <zack@codesourcery.com>
+
+ * 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 <mark@codesourcery.com>
* class.c (dfs_find_final_overrider): Adjust so that the most
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index c14287b0202..a4025ac1fa2 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 898dacb3668..362ddd18b57 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 a70b1b2daf1..1bac17cb312 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 2517dd271f8..8e8b168583d 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;