diff mbox

[C] Fold C_MAYBE_CONST_EXPRs with C_MAYBE_CONST_EXPR_INT_OPERANDS set (PR c/66066)

Message ID 20150513134222.GB27320@redhat.com
State New
Headers show

Commit Message

Marek Polacek May 13, 2015, 1:42 p.m. UTC
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  <polacek@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.


	Marek
diff mbox

Patch

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" } */