diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index d0b6559437675f0dc88d059aefe4388bed62d5c8..b8e807e11a9aa080cea8b2c6193bd0e10afc7108 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,10 @@ +2020-01-13 Joseph Myers <joseph@codesourcery.com> + + PR c/93241 + * c-typeck.c (build_c_cast): Check for expressions with integer + operands that can occur in an unevaluated part of an integer + constant expression and call note_integer_operands as needed. + 2019-01-08 Richard Biener <rguenther@suse.de> PR middle-end/93199 diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index c746f23b33630ce38087037b5a3436d6a6f615c6..9866c83faf22cf34eccd538133fde7cb5ef845cf 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -5709,6 +5709,8 @@ build_c_cast (location_t loc, tree type, tree expr) { tree value; + bool int_operands = EXPR_INT_CONST_OPERANDS (expr); + if (TREE_CODE (expr) == EXCESS_PRECISION_EXPR) expr = TREE_OPERAND (expr, 0); @@ -5943,6 +5945,14 @@ build_c_cast (location_t loc, tree type, tree expr) || TREE_CODE (expr) == COMPLEX_CST))) value = build1 (NOP_EXPR, type, value); + /* If the expression has integer operands and so can occur in an + unevaluated part of an integer constant expression, ensure the + return value reflects this. */ + if (int_operands + && INTEGRAL_TYPE_P (type) + && !EXPR_INT_CONST_OPERANDS (value)) + value = note_integer_operands (value); + protected_set_expr_location (value, loc); return value; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f14638c5079a322ca4c23cf24c729f263a9f5492..976003a0739b5b7db88208348f74aabf6e5ba64f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2020-01-13 Joseph Myers <joseph@codesourcery.com> + + PR c/93241 + * gcc.dg/c11-static-assert-10.c, gcc.dg/c99-const-expr-15.c: New + tests. + 2020-01-13 Martin Sebor <msebor@redhat.com> PR tree-optimization/93213 diff --git a/gcc/testsuite/gcc.dg/c11-static-assert-10.c b/gcc/testsuite/gcc.dg/c11-static-assert-10.c new file mode 100644 index 0000000000000000000000000000000000000000..2fe210b6cc8723398cb4cdf37b679ac5fac9007f --- /dev/null +++ b/gcc/testsuite/gcc.dg/c11-static-assert-10.c @@ -0,0 +1,9 @@ +/* Test for constant expressions: casts with integer overflow. PR + c/93241. */ +/* { dg-do compile } */ +/* { dg-options "-std=c11 -pedantic-errors" } */ + +#include <limits.h> + +_Static_assert (0 ? (_Bool) (INT_MAX + 1) : 1, ""); +_Static_assert (0 ? (short) ((INT_MAX + 1) != 0) : 1, ""); diff --git a/gcc/testsuite/gcc.dg/c99-const-expr-15.c b/gcc/testsuite/gcc.dg/c99-const-expr-15.c new file mode 100644 index 0000000000000000000000000000000000000000..b1744b671826ed7742623e96c3cd516109e10e74 --- /dev/null +++ b/gcc/testsuite/gcc.dg/c99-const-expr-15.c @@ -0,0 +1,9 @@ +/* Test for constant expressions: casts with integer overflow. PR + c/93241. */ +/* { dg-do compile } */ +/* { dg-options "-std=c99 -pedantic-errors" } */ + +#include <limits.h> + +struct s { int a : (0 ? (_Bool) (INT_MAX + 1) : 1); }; +struct t { int a : (0 ? (short) ((INT_MAX + 1) != 0) : 1); };