Ok. On Mar 1, 2018 4:38 PM, "Marek Polacek" <pola...@redhat.com> wrote:
> On Thu, Mar 01, 2018 at 02:29:47PM -0500, Jason Merrill wrote: > > I think this should happen in the block with maybe_constant_value; > > cp_fold_rvalue doesn't do this. > > This, then: > > Bootstrapped/regtested on x86_64-linux, ok for trunk? > > 2018-03-01 Marek Polacek <pola...@redhat.com> > > PR c++/84590 > * cp-gimplify.c (cp_fully_fold): Unwrap TARGET_EXPR or a > CONSTRUCTOR > wrapped in VIEW_CONVERT_EXPR. > > * c-c++-common/ubsan/shift-11.c: New test. > > diff --git gcc/cp/cp-gimplify.c gcc/cp/cp-gimplify.c > index 55a9d278dbe..0ddd435454c 100644 > --- gcc/cp/cp-gimplify.c > +++ gcc/cp/cp-gimplify.c > @@ -2037,7 +2037,17 @@ cp_fully_fold (tree x) > /* FIXME cp_fold ought to be a superset of maybe_constant_value so we > don't > have to call both. */ > if (cxx_dialect >= cxx11) > - x = maybe_constant_value (x); > + { > + x = maybe_constant_value (x); > + /* Sometimes we are given a CONSTRUCTOR but the call above wraps it > into > + a TARGET_EXPR; undo that here. */ > + if (TREE_CODE (x) == TARGET_EXPR) > + x = TARGET_EXPR_INITIAL (x); > + else if (TREE_CODE (x) == VIEW_CONVERT_EXPR > + && TREE_CODE (TREE_OPERAND (x, 0)) == CONSTRUCTOR > + && TREE_TYPE (TREE_OPERAND (x, 0)) == TREE_TYPE (x)) > + x = TREE_OPERAND (x, 0); > + } > return cp_fold_rvalue (x); > } > > diff --git gcc/testsuite/c-c++-common/ubsan/shift-11.c > gcc/testsuite/c-c++-common/ubsan/shift-11.c > index e69de29bb2d..03a72e217a2 100644 > --- gcc/testsuite/c-c++-common/ubsan/shift-11.c > +++ gcc/testsuite/c-c++-common/ubsan/shift-11.c > @@ -0,0 +1,13 @@ > +/* PR c++/84590 */ > +/* { dg-do compile } */ > +/* { dg-options "-fsanitize=shift" } */ > + > +struct S { > + int b; > +}; > + > +void > +fn (void) > +{ > + struct S c1 = { 1 << -1 }; /* { dg-warning "left shift" } */ > +} > > Marek >