The following is an attempt to implement what Joseph outlined here: <https://gcc.gnu.org/ml/gcc-patches/2015-05/msg01015.html>. This patch relies on the match.pd I've just posted. It shouldn't reduce e.g. division by zero to pedwarn-if-pedantic (the tests test that). But e.g. enum { A = 1 << -5 }; is already pedwarns-if-pedantic, and this patch doesn't change that. (It's especially important that this patch doesn't regress any of overflow-warn-?.c tests.)
Bootstrapped/regtested on x86_64-linux, ok for trunk? 2015-05-13 Marek Polacek <pola...@redhat.com> PR c/66066 * c-common.c (c_fully_fold_internal): Fold C_MAYBE_CONST_EXPRs with C_MAYBE_CONST_EXPR_INT_OPERANDS set. * c-typeck.c (digest_init): Call pedwarn_init with OPT_Wpedantic rather than with 0. * gcc.dg/pr19984.c: Add -Wpedantic. * gcc.dg/pr14649-1.c: Likewise. * gcc.dg/pr66066-1.c: New test. * gcc.dg/pr66066-2.c: New test. * gcc.dg/pr66066-3.c: New test. diff --git gcc/c-family/c-common.c gcc/c-family/c-common.c index 7e5ac72..24200f0 100644 --- gcc/c-family/c-common.c +++ gcc/c-family/c-common.c @@ -1209,7 +1209,11 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands, if (C_MAYBE_CONST_EXPR_NON_CONST (expr)) *maybe_const_operands = false; if (C_MAYBE_CONST_EXPR_INT_OPERANDS (expr)) - *maybe_const_itself = false; + { + *maybe_const_itself = false; + inner = c_fully_fold_internal (inner, in_init, maybe_const_operands, + maybe_const_itself); + } if (pre && !in_init) ret = build2 (COMPOUND_EXPR, TREE_TYPE (expr), pre, inner); else diff --git gcc/c/c-typeck.c gcc/c/c-typeck.c index 3fcb7c2..9b883a2 100644 --- gcc/c/c-typeck.c +++ gcc/c/c-typeck.c @@ -6864,7 +6864,7 @@ digest_init (location_t init_loc, tree type, tree init, tree origtype, inside_init = error_mark_node; } else if (require_constant && !maybe_const) - pedwarn_init (init_loc, 0, + pedwarn_init (init_loc, OPT_Wpedantic, "initializer element is not a constant expression"); /* Added to enable additional -Wsuggest-attribute=format warnings. */ diff --git gcc/testsuite/gcc.dg/pr14649-1.c gcc/testsuite/gcc.dg/pr14649-1.c index 34f42f0..b9fc4b9 100644 --- gcc/testsuite/gcc.dg/pr14649-1.c +++ gcc/testsuite/gcc.dg/pr14649-1.c @@ -1,6 +1,6 @@ /* PR c/14649 */ /* { dg-do compile } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -Wpedantic" } */ double atan(double); diff --git gcc/testsuite/gcc.dg/pr19984.c gcc/testsuite/gcc.dg/pr19984.c index 5323c46..a628e0e 100644 --- gcc/testsuite/gcc.dg/pr19984.c +++ gcc/testsuite/gcc.dg/pr19984.c @@ -1,6 +1,6 @@ /* PR c/19984 */ /* { dg-do compile } */ -/* { dg-options "-O2 -std=c99" } */ +/* { dg-options "-O2 -std=c99 -Wpedantic" } */ double nan (const char *); diff --git gcc/testsuite/gcc.dg/pr66066-1.c gcc/testsuite/gcc.dg/pr66066-1.c index e69de29..7a1d342 100644 --- gcc/testsuite/gcc.dg/pr66066-1.c +++ gcc/testsuite/gcc.dg/pr66066-1.c @@ -0,0 +1,37 @@ +/* PR c/66066 */ +/* { dg-do compile } */ +/* { dg-options "-Wno-div-by-zero" } */ + +/* Accept these unless -pedantic-errors/-Werror. */ +int a1 = -1 << 0; +int a2 = -1 << 0 | 0; +int a3 = -1 << 0 & 1; +int a4 = -1 << 2 ^ 1; +int a5 = 4 & -1 << 2; +int a6 = (-1 << 2) ^ (1 >> 1); +int a7 = 0 || (-1 << 1); +int a8 = 0 ? 2 : (-1 << 1); +int a9 = 1 && -1 << 0; +int a10 = !(-1 << 0); + +/* Don't accept these. */ +int b1 = 1 / 0; /* { dg-error "initializer element is not constant" } */ +int b2 = 1 / (1 / 0); /* { dg-error "initializer element is not constant" } */ +int b3 = 0 ? 2 : 1 / 0; /* { dg-error "initializer element is not constant" } */ +int b4 = 0 || 1 / 0; /* { dg-error "initializer element is not constant" } */ +int b5 = 0 * (1 / 0); /* { dg-error "initializer element is not constant" } */ +int b6 = 1 * (1 / 0); /* { dg-error "initializer element is not constant" } */ +int b7 = (1 / 0) * 0; /* { dg-error "initializer element is not constant" } */ +int b8 = (1 / 0) * 1; /* { dg-error "initializer element is not constant" } */ +int b9 = 1 && 1 / 0; /* { dg-error "initializer element is not constant" } */ +int b10 = !(1 / 0); /* { dg-error "initializer element is not constant" } */ +int c1 = 1 % 0; /* { dg-error "initializer element is not constant" } */ +int c2 = 1 / (1 % 0); /* { dg-error "initializer element is not constant" } */ +int c3 = 0 ? 2 : 1 % 0; /* { dg-error "initializer element is not constant" } */ +int c4 = 0 || 1 % 0; /* { dg-error "initializer element is not constant" } */ +int c5 = 0 * (1 % 0); /* { dg-error "initializer element is not constant" } */ +int c6 = 1 * (1 % 0); /* { dg-error "initializer element is not constant" } */ +int c7 = (1 % 0) * 0; /* { dg-error "initializer element is not constant" } */ +int c8 = (1 % 0) * 1; /* { dg-error "initializer element is not constant" } */ +int c9 = 1 && 1 % 0; /* { dg-error "initializer element is not constant" } */ +int c10 = !(1 % 0); /* { dg-error "initializer element is not constant" } */ diff --git gcc/testsuite/gcc.dg/pr66066-2.c gcc/testsuite/gcc.dg/pr66066-2.c index e69de29..848fe85 100644 --- gcc/testsuite/gcc.dg/pr66066-2.c +++ gcc/testsuite/gcc.dg/pr66066-2.c @@ -0,0 +1,37 @@ +/* PR c/66066 */ +/* { dg-do compile } */ +/* { dg-options "-Wno-div-by-zero -Wpedantic" } */ + +/* Accept these unless -pedantic-errors/-Werror. */ +int a1 = -1 << 0; /* { dg-warning "initializer element is not a constant expression" } */ +int a2 = -1 << 0 | 0; /* { dg-warning "initializer element is not a constant expression" } */ +int a3 = -1 << 0 & 1; /* { dg-warning "initializer element is not a constant expression" } */ +int a4 = -1 << 2 ^ 1; /* { dg-warning "initializer element is not a constant expression" } */ +int a5 = 4 & -1 << 2; /* { dg-warning "initializer element is not a constant expression" } */ +int a6 = (-1 << 2) ^ (1 >> 1); /* { dg-warning "initializer element is not a constant expression" } */ +int a7 = 0 || (-1 << 1); /* { dg-warning "initializer element is not a constant expression" } */ +int a8 = 0 ? 2 : (-1 << 1); /* { dg-warning "initializer element is not a constant expression" } */ +int a9 = 1 && -1 << 0; /* { dg-warning "initializer element is not a constant expression" } */ +int a10 = !(-1 << 0); /* { dg-warning "initializer element is not a constant expression" } */ + +/* Don't accept these. */ +int b1 = 1 / 0; /* { dg-error "initializer element is not constant" } */ +int b2 = 1 / (1 / 0); /* { dg-error "initializer element is not constant" } */ +int b3 = 0 ? 2 : 1 / 0; /* { dg-error "initializer element is not constant" } */ +int b4 = 0 || 1 / 0; /* { dg-error "initializer element is not constant" } */ +int b5 = 0 * (1 / 0); /* { dg-error "initializer element is not constant" } */ +int b6 = 1 * (1 / 0); /* { dg-error "initializer element is not constant" } */ +int b7 = (1 / 0) * 0; /* { dg-error "initializer element is not constant" } */ +int b8 = (1 / 0) * 1; /* { dg-error "initializer element is not constant" } */ +int b9 = 1 && 1 / 0; /* { dg-error "initializer element is not constant" } */ +int b10 = !(1 / 0); /* { dg-error "initializer element is not constant" } */ +int c1 = 1 % 0; /* { dg-error "initializer element is not constant" } */ +int c2 = 1 / (1 % 0); /* { dg-error "initializer element is not constant" } */ +int c3 = 0 ? 2 : 1 % 0; /* { dg-error "initializer element is not constant" } */ +int c4 = 0 || 1 % 0; /* { dg-error "initializer element is not constant" } */ +int c5 = 0 * (1 % 0); /* { dg-error "initializer element is not constant" } */ +int c6 = 1 * (1 % 0); /* { dg-error "initializer element is not constant" } */ +int c7 = (1 % 0) * 0; /* { dg-error "initializer element is not constant" } */ +int c8 = (1 % 0) * 1; /* { dg-error "initializer element is not constant" } */ +int c9 = 1 && 1 % 0; /* { dg-error "initializer element is not constant" } */ +int c10 = !(1 % 0); /* { dg-error "initializer element is not constant" } */ diff --git gcc/testsuite/gcc.dg/pr66066-3.c gcc/testsuite/gcc.dg/pr66066-3.c index e69de29..99ffec6 100644 --- gcc/testsuite/gcc.dg/pr66066-3.c +++ gcc/testsuite/gcc.dg/pr66066-3.c @@ -0,0 +1,37 @@ +/* PR c/66066 */ +/* { dg-do compile } */ +/* { dg-options "-Wno-div-by-zero -pedantic-errors" } */ + +/* Accept these unless -pedantic-errors/-Werror. */ +int a1 = -1 << 0; /* { dg-error "initializer element is not a constant expression" } */ +int a2 = -1 << 0 | 0; /* { dg-error "initializer element is not a constant expression" } */ +int a3 = -1 << 0 & 1; /* { dg-error "initializer element is not a constant expression" } */ +int a4 = -1 << 2 ^ 1; /* { dg-error "initializer element is not a constant expression" } */ +int a5 = 4 & -1 << 2; /* { dg-error "initializer element is not a constant expression" } */ +int a6 = (-1 << 2) ^ (1 >> 1); /* { dg-error "initializer element is not a constant expression" } */ +int a7 = 0 || (-1 << 1); /* { dg-error "initializer element is not a constant expression" } */ +int a8 = 0 ? 2 : (-1 << 1); /* { dg-error "initializer element is not a constant expression" } */ +int a9 = 1 && -1 << 0; /* { dg-error "initializer element is not a constant expression" } */ +int a10 = !(-1 << 0); /* { dg-error "initializer element is not a constant expression" } */ + +/* Don't accept these. */ +int b1 = 1 / 0; /* { dg-error "initializer element is not constant" } */ +int b2 = 1 / (1 / 0); /* { dg-error "initializer element is not constant" } */ +int b3 = 0 ? 2 : 1 / 0; /* { dg-error "initializer element is not constant" } */ +int b4 = 0 || 1 / 0; /* { dg-error "initializer element is not constant" } */ +int b5 = 0 * (1 / 0); /* { dg-error "initializer element is not constant" } */ +int b6 = 1 * (1 / 0); /* { dg-error "initializer element is not constant" } */ +int b7 = (1 / 0) * 0; /* { dg-error "initializer element is not constant" } */ +int b8 = (1 / 0) * 1; /* { dg-error "initializer element is not constant" } */ +int b9 = 1 && 1 / 0; /* { dg-error "initializer element is not constant" } */ +int b10 = !(1 / 0); /* { dg-error "initializer element is not constant" } */ +int c1 = 1 % 0; /* { dg-error "initializer element is not constant" } */ +int c2 = 1 / (1 % 0); /* { dg-error "initializer element is not constant" } */ +int c3 = 0 ? 2 : 1 % 0; /* { dg-error "initializer element is not constant" } */ +int c4 = 0 || 1 % 0; /* { dg-error "initializer element is not constant" } */ +int c5 = 0 * (1 % 0); /* { dg-error "initializer element is not constant" } */ +int c6 = 1 * (1 % 0); /* { dg-error "initializer element is not constant" } */ +int c7 = (1 % 0) * 0; /* { dg-error "initializer element is not constant" } */ +int c8 = (1 % 0) * 1; /* { dg-error "initializer element is not constant" } */ +int c9 = 1 && 1 % 0; /* { dg-error "initializer element is not constant" } */ +int c10 = !(1 % 0); /* { dg-error "initializer element is not constant" } */ Marek