Hi! On Thu, Jun 19, 2014 at 04:56:53PM +0200, Marek Polacek wrote:
Thanks for working on this. > --- gcc/asan.c > +++ gcc/asan.c > @@ -2761,6 +2761,9 @@ pass_sanopt::execute (function *fun) > case IFN_UBSAN_NULL: > ubsan_expand_null_ifn (gsi); > break; > + case IFN_UBSAN_BOUNDS: > + ubsan_expand_bounds_btn (&gsi); > + break; > default: Why *_btn instead of *_ifn ? > +static tree > +ubsan_walk_array_refs_r (tree *tp, int *walk_subtrees, void *data) > +{ > + struct pointer_set_t *pset = (struct pointer_set_t *) data; > + > + if (TREE_CODE (*tp) == BIND_EXPR) > + { I think it would be worth adding here a comment why do you handle BIND_EXPR here, that it doesn't walk the vars, but only their initializers etc. and thus in order to prevent walking DECL_INITIAL of TREE_STATIC decls we have to duplicate this part of walk_tree. > + for (tree decl = BIND_EXPR_VARS (*tp); decl; decl = DECL_CHAIN (decl)) > + { > + if (TREE_STATIC (decl)) > + { > + *walk_subtrees = 0; > + continue; > + } > + walk_tree (&DECL_INITIAL (decl), ubsan_walk_array_refs_r, NULL, pset); > + walk_tree (&DECL_SIZE (decl), ubsan_walk_array_refs_r, NULL, pset); > + walk_tree (&DECL_SIZE_UNIT (decl), ubsan_walk_array_refs_r, NULL, > pset); Shouldn't that use pset, pset); or data, pset); ? Also, too long lines (at least the last one, first one likely too). > + tree bound = TYPE_MAX_VALUE (domain); > + if (ignore_off_by_one) > + bound = fold_build2 (PLUS_EXPR, TREE_TYPE (bound), bound, > + build_int_cst (TREE_TYPE (bound), 1)); > + > + /* Detect flexible array members and suchlike. */ > + tree base = get_base_address (array); > + if (base && TREE_CODE (base) == INDIRECT_REF) I'd check also == MEM_REF here, while the FEs often use INDIRECT_REFs, there are already spots where it creates MEM_REFs. > +void > +ubsan_maybe_instrument_array_ref (tree *expr_p, bool ignore_off_by_one) > +{ > + if (!ubsan_array_ref_instrumented_p (*expr_p) > + && current_function_decl != 0 Please use != NULL_TREE. > + && !lookup_attribute ("no_sanitize_undefined", > + DECL_ATTRIBUTES (current_function_decl))) > + { > + tree t = copy_node (*expr_p); > + tree op0 = TREE_OPERAND (t, 0); > + tree op1 = TREE_OPERAND (t, 1); Please don't call copy_node until you know you want to instrument it. I.e. tree op0 = TREE_OPERAND (*expr_p, 0); tree op1 = TREE_OPERAND (*expr_p, 1); > + tree e = ubsan_instrument_bounds (EXPR_LOCATION (t), op0, &op1, s/t/*expr_p/ above. > + ignore_off_by_one); > + if (e != NULL_TREE) > + { and only here add: tree t = copy_node (*expr_p); > + TREE_OPERAND (t, 1) = build2 (COMPOUND_EXPR, TREE_TYPE (op1), > + e, op1); > + *expr_p = t; > + } > + } > +} > --- gcc/tree-pretty-print.c > +++ gcc/tree-pretty-print.c > @@ -3218,6 +3218,13 @@ print_call_name (pretty_printer *buffer, tree node, > int flags) > { > tree op0 = node; > > + if (node == NULL_TREE) > + { > + /* TODO Print builtin name. */ > + pp_string (buffer, "<internal function call>"); Use internal_fn_name function? Jakub