Commit fefbfa21 by Frank Ch. Eigler Committed by Frank Ch. Eigler

tree-mudflap.c (mf_build_check_statement_for): Reorganize to take check-base and -limit arguments.

2004-10-02  Frank Ch. Eigler  <fche@redhat.com>

	* tree-mudflap.c (mf_build_check_statement_for): Reorganize to
	take check-base and -limit arguments.
	(mf_xform_derefs_1): Reorganize slightly to pass proper base/limit
	check ranges for ARRAY_REF and COMPONENT_REF.
	(execute_mudflap_fnction_ops, ..._decls): Limit unnecessary
	instrumentation.

2004-10-02  Frank Ch. Eigler  <fche@redhat.com>

	* testsuite/libmudflap.c/pass50-frag.c, fail33-frag.c, fail34-frag.c:
	New tests for proper base/limit checking for aggregates.

From-SVN: r88432
parent 7848dfca
2004-10-02 Frank Ch. Eigler <fche@redhat.com>
* tree-mudflap.c (mf_build_check_statement_for): Reorganize to
take check-base and -limit arguments.
(mf_xform_derefs_1): Reorganize slightly to pass proper base/limit
check ranges for ARRAY_REF and COMPONENT_REF.
(execute_mudflap_fnction_ops, ..._decls): Limit unnecessary
instrumentation.
2004-10-02 Joseph S. Myers <jsm@polyomino.org.uk> 2004-10-02 Joseph S. Myers <jsm@polyomino.org.uk>
* c-objc-common.c (c_tree_printer): Correct description of %E. * c-objc-common.c (c_tree_printer): Correct description of %E.
......
...@@ -407,7 +407,10 @@ mudflap_init (void) ...@@ -407,7 +407,10 @@ mudflap_init (void)
static void static void
execute_mudflap_function_ops (void) execute_mudflap_function_ops (void)
{ {
if (mf_marked_p (current_function_decl)) /* Don't instrument functions such as the synthetic constructor
built during mudflap_finish_file. */
if (mf_marked_p (current_function_decl) ||
DECL_ARTIFICIAL (current_function_decl))
return; return;
push_gimplify_context (); push_gimplify_context ();
...@@ -481,7 +484,7 @@ mf_decl_clear_locals (void) ...@@ -481,7 +484,7 @@ mf_decl_clear_locals (void)
} }
static void static void
mf_build_check_statement_for (tree addr, tree size, mf_build_check_statement_for (tree base, tree addr, tree limit,
block_stmt_iterator *instr_bsi, block_stmt_iterator *instr_bsi,
location_t *locus, tree dirflag) location_t *locus, tree dirflag)
{ {
...@@ -494,6 +497,7 @@ mf_build_check_statement_for (tree addr, tree size, ...@@ -494,6 +497,7 @@ mf_build_check_statement_for (tree addr, tree size,
tree mf_value; tree mf_value;
tree mf_base; tree mf_base;
tree mf_elem; tree mf_elem;
tree mf_limit;
/* We first need to split the current basic block, and start altering /* We first need to split the current basic block, and start altering
the CFG. This allows us to insert the statements we're about to the CFG. This allows us to insert the statements we're about to
...@@ -557,6 +561,7 @@ mf_build_check_statement_for (tree addr, tree size, ...@@ -557,6 +561,7 @@ mf_build_check_statement_for (tree addr, tree size,
mf_value = create_tmp_var (ptrtype, "__mf_value"); mf_value = create_tmp_var (ptrtype, "__mf_value");
mf_elem = create_tmp_var (mf_cache_structptr_type, "__mf_elem"); mf_elem = create_tmp_var (mf_cache_structptr_type, "__mf_elem");
mf_base = create_tmp_var (mf_uintptr_type, "__mf_base"); mf_base = create_tmp_var (mf_uintptr_type, "__mf_base");
mf_limit = create_tmp_var (mf_uintptr_type, "__mf_limit");
/* Build: __mf_value = <address expression>. */ /* Build: __mf_value = <address expression>. */
t = build (MODIFY_EXPR, void_type_node, mf_value, unshare_expr (addr)); t = build (MODIFY_EXPR, void_type_node, mf_value, unshare_expr (addr));
...@@ -565,9 +570,16 @@ mf_build_check_statement_for (tree addr, tree size, ...@@ -565,9 +570,16 @@ mf_build_check_statement_for (tree addr, tree size,
head = tsi_start (t); head = tsi_start (t);
tsi = tsi_last (t); tsi = tsi_last (t);
/* Build: __mf_base = (uintptr_t)__mf_value. */ /* Build: __mf_base = (uintptr_t) <base address expression>. */
t = build (MODIFY_EXPR, void_type_node, mf_base, t = build (MODIFY_EXPR, void_type_node, mf_base,
build1 (NOP_EXPR, mf_uintptr_type, mf_value)); convert (mf_uintptr_type, unshare_expr (base)));
SET_EXPR_LOCUS (t, locus);
gimplify_to_stmt_list (&t);
tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
/* Build: __mf_limit = (uintptr_t) <limit address expression>. */
t = build (MODIFY_EXPR, void_type_node, mf_limit,
convert (mf_uintptr_type, unshare_expr (limit)));
SET_EXPR_LOCUS (t, locus); SET_EXPR_LOCUS (t, locus);
gimplify_to_stmt_list (&t); gimplify_to_stmt_list (&t);
tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING); tsi_link_after (&tsi, t, TSI_CONTINUE_LINKING);
...@@ -590,7 +602,7 @@ mf_build_check_statement_for (tree addr, tree size, ...@@ -590,7 +602,7 @@ mf_build_check_statement_for (tree addr, tree size,
/* Quick validity check. /* Quick validity check.
if (__mf_elem->low > __mf_base if (__mf_elem->low > __mf_base
|| (__mf_elem_high < __mf_base + sizeof(T) - 1)) || (__mf_elem_high < __mf_limit))
{ {
__mf_check (); __mf_check ();
... and only if single-threaded: ... and only if single-threaded:
...@@ -607,22 +619,19 @@ mf_build_check_statement_for (tree addr, tree size, ...@@ -607,22 +619,19 @@ mf_build_check_statement_for (tree addr, tree size,
TYPE_FIELDS (mf_cache_struct_type), NULL_TREE); TYPE_FIELDS (mf_cache_struct_type), NULL_TREE);
t = build (GT_EXPR, boolean_type_node, t, mf_base); t = build (GT_EXPR, boolean_type_node, t, mf_base);
/* Construct '__mf_elem->high < __mf_base + sizeof(T) - 1'. /* Construct '__mf_elem->high < __mf_limit'.
First build: First build:
1) u <-- '__mf_elem->high' 1) u <-- '__mf_elem->high'
2) v <-- '__mf_base + sizeof (T) - 1'. 2) v <-- '__mf_limit'.
Then build 'u <-- (u < v). */ Then build 'u <-- (u < v). */
u = build (COMPONENT_REF, mf_uintptr_type, u = build (COMPONENT_REF, mf_uintptr_type,
build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem), build1 (INDIRECT_REF, mf_cache_struct_type, mf_elem),
TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)), NULL_TREE); TREE_CHAIN (TYPE_FIELDS (mf_cache_struct_type)), NULL_TREE);
v = convert (mf_uintptr_type, v = mf_limit;
size_binop (MINUS_EXPR, size, size_one_node));
v = fold (build (PLUS_EXPR, mf_uintptr_type, mf_base, v));
u = build (LT_EXPR, boolean_type_node, u, v); u = build (LT_EXPR, boolean_type_node, u, v);
...@@ -647,7 +656,7 @@ mf_build_check_statement_for (tree addr, tree size, ...@@ -647,7 +656,7 @@ mf_build_check_statement_for (tree addr, tree size,
the conditional jump, the conditional jump,
if (__mf_elem->low > __mf_base if (__mf_elem->low > __mf_base
|| (__mf_elem_high < __mf_base + sizeof(T) - 1)) || (__mf_elem_high < __mf_limit))
The lowered GIMPLE tree representing this code is in the statement The lowered GIMPLE tree representing this code is in the statement
list starting at 'head'. list starting at 'head'.
...@@ -670,8 +679,14 @@ mf_build_check_statement_for (tree addr, tree size, ...@@ -670,8 +679,14 @@ mf_build_check_statement_for (tree addr, tree size,
: *locus), : *locus),
NULL_TREE); NULL_TREE);
u = tree_cons (NULL_TREE, dirflag, u); u = tree_cons (NULL_TREE, dirflag, u);
u = tree_cons (NULL_TREE, size, u); /* NB: we pass the overall [base..limit] range to mf_check,
u = tree_cons (NULL_TREE, mf_value, u); not the [mf_value..mf_value+size-1] range. */
u = tree_cons (NULL_TREE,
fold (build (PLUS_EXPR, integer_type_node,
fold (build (MINUS_EXPR, mf_uintptr_type, mf_limit, mf_base)),
integer_one_node)),
u);
u = tree_cons (NULL_TREE, mf_base, u);
t = build_function_call_expr (mf_check_fndecl, u); t = build_function_call_expr (mf_check_fndecl, u);
gimplify_to_stmt_list (&t); gimplify_to_stmt_list (&t);
head = tsi_start (t); head = tsi_start (t);
...@@ -701,7 +716,7 @@ static void ...@@ -701,7 +716,7 @@ static void
mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp, mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp,
location_t *locus, tree dirflag) location_t *locus, tree dirflag)
{ {
tree type, ptr_type, addr, size, t; tree type, ptr_type, addr, base, size, limit, t;
/* Don't instrument read operations. */ /* Don't instrument read operations. */
if (dirflag == integer_zero_node && flag_mudflap_ignore_reads) if (dirflag == integer_zero_node && flag_mudflap_ignore_reads)
...@@ -756,12 +771,20 @@ mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp, ...@@ -756,12 +771,20 @@ mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp,
/* If we got here, we couldn't statically the check. */ /* If we got here, we couldn't statically the check. */
ptr_type = build_pointer_type (type); ptr_type = build_pointer_type (type);
addr = build1 (ADDR_EXPR, ptr_type, t); addr = build1 (ADDR_EXPR, ptr_type, t);
base = build1 (ADDR_EXPR, ptr_type, op0);
limit = fold (build (MINUS_EXPR, mf_uintptr_type,
fold (build2 (PLUS_EXPR, mf_uintptr_type, addr, size)),
integer_one_node));
} }
break; break;
case INDIRECT_REF: case INDIRECT_REF:
addr = TREE_OPERAND (t, 0); addr = TREE_OPERAND (t, 0);
ptr_type = TREE_TYPE (addr); ptr_type = TREE_TYPE (addr);
base = addr;
limit = fold (build (MINUS_EXPR, ptr_type_node,
fold (build (PLUS_EXPR, ptr_type_node, base, size)),
integer_one_node));
break; break;
case ARRAY_RANGE_REF: case ARRAY_RANGE_REF:
...@@ -798,6 +821,12 @@ mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp, ...@@ -798,6 +821,12 @@ mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp,
ptr_type = build_pointer_type (type); ptr_type = build_pointer_type (type);
addr = build1 (ADDR_EXPR, ptr_type, t); addr = build1 (ADDR_EXPR, ptr_type, t);
} }
/* XXXXXX */
base = addr;
limit = fold (build (MINUS_EXPR, ptr_type_node,
fold (build (PLUS_EXPR, ptr_type_node, base, size)),
integer_one_node));
} }
break; break;
...@@ -823,6 +852,11 @@ mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp, ...@@ -823,6 +852,11 @@ mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp,
addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0); addr = TREE_OPERAND (TREE_OPERAND (t, 0), 0);
addr = convert (ptr_type_node, addr); addr = convert (ptr_type_node, addr);
addr = fold (build (PLUS_EXPR, ptr_type_node, addr, ofs)); addr = fold (build (PLUS_EXPR, ptr_type_node, addr, ofs));
base = addr;
limit = fold (build (MINUS_EXPR, ptr_type_node,
fold (build (PLUS_EXPR, ptr_type_node, base, size)),
integer_one_node));
} }
break; break;
...@@ -830,7 +864,7 @@ mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp, ...@@ -830,7 +864,7 @@ mf_xform_derefs_1 (block_stmt_iterator *iter, tree *tp,
return; return;
} }
mf_build_check_statement_for (addr, size, iter, locus, dirflag); mf_build_check_statement_for (base, addr, limit, iter, locus, dirflag);
} }
static void static void
...@@ -891,7 +925,10 @@ mf_xform_derefs (void) ...@@ -891,7 +925,10 @@ mf_xform_derefs (void)
static void static void
execute_mudflap_function_decls (void) execute_mudflap_function_decls (void)
{ {
if (mf_marked_p (current_function_decl)) /* Don't instrument functions such as the synthetic constructor
built during mudflap_finish_file. */
if (mf_marked_p (current_function_decl) ||
DECL_ARTIFICIAL (current_function_decl))
return; return;
push_gimplify_context (); push_gimplify_context ();
......
2004-10-02 Frank Ch. Eigler <fche@redhat.com>
* testsuite/libmudflap.c/pass50-frag.c, fail33-frag.c, fail34-frag.c:
New tests for proper base/limit checking for aggregates.
2004-09-15 Joseph S. Myers <jsm@polyomino.org.uk> 2004-09-15 Joseph S. Myers <jsm@polyomino.org.uk>
* testsuite/libmudflap.c/pass35-frag.c: Update expected message. * testsuite/libmudflap.c/pass35-frag.c: Update expected message.
......
#include <stdlib.h>
#define SIZE 16
char b[SIZE];
char a[SIZE];
int main ()
{
int i, j=0;
int a_before_b = (& a[0] < & b[0]);
/* Rather than iterating linearly, which would allow loop unrolling
and mapping to pointer manipulation, we traverse the "joined"
arrays in some random order. */
for (i=0; i<SIZE*2; i++)
{
k=rand()%(SIZE*2))
j += (a_before_b ? a[k] : b[k]);
}
return j;
}
/* { dg-output "mudflap violation 1.*" } */
/* { dg-output "Nearby object.*" } */
/* { dg-output "mudflap object.*\[ab\]" } */
/* { dg-do run { xfail *-*-* } } */
#include <stdlib.h>
struct s
{
int a1[4];
};
struct s a, b;
int idx = 7; /* should pass to the next object */
int
main ()
{
int i, j=0;
int a_before_b = (& a < & b);
j = (a_before_b ? a.a1[idx] : b.a1[idx]);
return j;
}
/* { dg-output "mudflap violation 1.*" } */
/* { dg-output "Nearby object.*" } */
/* { dg-output "mudflap object.*\[ab\]" } */
/* { dg-do run { xfail *-*-* } } */
#include <stdlib.h>
struct a
{
int a1[5];
union
{
int b1[5];
struct
{
int c1;
int c2;
} b2[4];
} a2[8];
};
int i1 = 5;
int i2 = 2;
int i3 = 6;
int i4 = 0;
int
main ()
{
volatile struct a *k = calloc (1, sizeof (struct a));
k->a2[i1].b1[i2] = k->a2[i3].b2[i4].c2;
free ((void *) k);
return 0;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment