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