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

Reply via email to