From 3d77686d2eddf76d3498169d0ca5653db45a8662 Mon Sep 17 00:00:00 2001 From: Joseph Myers Date: Mon, 13 Jan 2020 16:39:04 +0000 Subject: [PATCH] Fix handling of overflow in C casts in integer constant expressions (PR c/93241). Bug 93241 reports a case where certain C expressions involving casts, that would not be valid in an evaluated part of an integer constant expression (because of e.g. involving integer overflow), are wrongly rejected in an unevaluated part of an integer constant expression even though all the operands and operations are ones that are valid in that context. This is a rejects-valid regression in GCC 4.5 and later relative to 4.4 (for some testcases; the one in the bug uses _Static_assert which isn't supported in those older releases). The rule in the C front end is that an expression with those properties (valid in an unevaluated part of an integer constant expression but not an evaluated part) must be represented either as an INTEGER_CST with TREE_OVERFLOW set or as a C_MAYBE_CONST_EXPR with C_MAYBE_CONST_EXPR_INT_OPERANDS set. This patch fixes build_c_cast to check for that case and call note_integer_operands as needed. Bootstrapped with no regressions for x86_64-pc-linux-gnu. PR c/93241 gcc/c: * 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. gcc/testsuite: * gcc.dg/c11-static-assert-10.c, gcc.dg/c99-const-expr-15.c: New tests. --- gcc/c/ChangeLog | 7 +++++++ gcc/c/c-typeck.c | 10 ++++++++++ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/c11-static-assert-10.c | 9 +++++++++ gcc/testsuite/gcc.dg/c99-const-expr-15.c | 9 +++++++++ 5 files changed, 41 insertions(+) create mode 100644 gcc/testsuite/gcc.dg/c11-static-assert-10.c create mode 100644 gcc/testsuite/gcc.dg/c99-const-expr-15.c diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index d0b65594376..b8e807e11a9 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,10 @@ +2020-01-13 Joseph Myers + + 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 PR middle-end/93199 diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index c746f23b336..9866c83faf2 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 f14638c5079..976003a0739 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2020-01-13 Joseph Myers + + PR c/93241 + * gcc.dg/c11-static-assert-10.c, gcc.dg/c99-const-expr-15.c: New + tests. + 2020-01-13 Martin Sebor 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 00000000000..2fe210b6cc8 --- /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 + +_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 00000000000..b1744b67182 --- /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 + +struct s { int a : (0 ? (_Bool) (INT_MAX + 1) : 1); }; +struct t { int a : (0 ? (short) ((INT_MAX + 1) != 0) : 1); }; -- 2.30.2