On Wed, Jul 22, 2015 at 07:43:23PM +0200, Jakub Jelinek wrote:
> On Wed, Jul 22, 2015 at 07:26:22PM +0200, Marek Polacek wrote:
> > In this testcase we were generating an uninitialized variable when doing
> > -fsanitize=shift,bounds sanitization.  The shift instrumentation is done
> > first; after that, the IR looks like
> > 
> >   res[i] = (m > 31) ? __ubsan (... tab[i] ...) ? 0, ... tab[i] ...;
> > 
> > where tab[i] are identical.  That means that when we instrument the first
> > tab[i] (we shouldn't do this I suppose), the second tab[i] is changed as
> > well as they're shared.  But that doesn't play well with SAVE_EXPRs, because
> > SAVE_EXPR <i> would only be initialized on one path.  Fixed by unsharing
> > the operands when constructing the ubsan check.  The .gimple diff is in
> > essence just
> > 
> > +  i.2 = i;
> > +  UBSAN_BOUNDS (0B, i.2, 21);
> > -  UBSAN_BOUNDS (0B, i.1, 21);
> > 
> > (Merely not instrumenting __ubsan_* wouldn't help exactly because of the
> > sharing.)
> > 
> > Bootstrapped/regtested on x86_64-linux, ok for trunk?
> 
> That is strange.  I'd have expected you'd want to unshare if you want to use
> the same operand multiple times in the same function, instead of unsharing
> it just in case it is shared with something different.
> 
> So isn't the bug instead that the UBSAN_BOUNDS generating code doesn't
> unshare?  Of course, these two functions use op0 and/or op1 sometimes
> multiple times too and thus they might want to unshare too, but I'd have
> expected in a different spot.

I don't think so: I think I need to unshare op0 and op1 because the shift
instrumentation always duplicates them for the __ubsan_* call.
Doing the unsharing in bounds instrumentation is too late (and none of my
attempts worked).

I can move the unsharing a little bit below, just before creating the
BUILT_IN_UBSAN_HANDLE_SHIFT_OUT_OF_BOUNDS call, but otherwise I have no
better ideas.

So for now I don't have a better patch, sorry.

        Marek

Reply via email to