On Fri, Oct 26, 2012 at 12:23:41AM +0200, Dodji Seketeli wrote:
> +/* Instrument the strlen builtin call pointed to by ITER.
> +
> +   This function instruments the access to the first byte of the
> +   argument, right before the call.  After the call it instruments the
> +   access to the last byte of the argument; it uses the result of the
> +   call to deduce the offset of that last byte.  */
> +
> +static void
> +instrument_strlen_call (gimple_stmt_iterator *iter)
> +{
> +  gimple call = gsi_stmt (*iter);
> +  gcc_assert (is_gimple_call (call));
> +
> +  tree callee = gimple_call_fndecl (call);
> +  gcc_assert (is_builtin_fn (callee)
> +           && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
> +           && DECL_FUNCTION_CODE (callee) == BUILT_IN_STRLEN);
> +
> +  location_t location = gimple_location (call);
I'd call the var just loc, that is far more commonly used and shorter.

> +  /* If we initially had an instruction like:
> +
> +      int n = strlen (str)
> +
> +     we now want to instrument the access to str[n-1], after the
> +     instruction above, if n is greater than 0.  */
> +
> +  /* So let's build the access to str[n-1], in a if (n > 0) {} block.  */
> +
> +  tree len = gimple_call_lhs (call);

I'd add
  if (len == NULL_TREE)
    return;
just in case.  While strlen is a pure function, not sure if some pass isn't
just clearing the lhs as unneeded without removing it immediately.

> +  /*  if (len > 0); */
> +  gimple cond = gimple_build_cond (GT_EXPR, len,
> +                                build_int_cst (size_type_node, 0),
> +                                NULL, NULL);

But more importantly, you shouldn't guard it with len > 0, and shouldn't
test str[n-1], but str[n] (also adjust the comment above).
Because strlen must read even the '\0' byte at str[n].


> +    case BUILT_IN_ATOMIC_FETCH_OR_16:
> +      {
> +     dest = gimple_call_arg (call, 0);
> +     /* So DEST represents the address of a memory location.
> +        instrument_derefs wants the memory location, so lets
> +        dereference the address DEST before handing it to
> +        instrument_derefs.  */
> +     if (TREE_CODE (dest) == ADDR_EXPR)
> +       dest = TREE_OPERAND (dest, 0);
> +     else if (TREE_CODE (dest) == SSA_NAME)
> +       dest = build2 (MEM_REF, TREE_TYPE (TREE_TYPE (dest)),
> +                      dest, build_int_cst (TREE_TYPE (dest), 0));
> +     else
> +       gcc_unreachable ();
> +
> +     instrument_derefs (iter, dest, location, is_store);
> +     return true;
> +      }

{} around this is unneeded I think.

Otherwise looks good.

        Jakub

Reply via email to