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
>

Reply via email to