This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Fix PR c/39613 (case labels and integer constant expressions)
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Thu, 9 Apr 2009 00:20:54 +0000 (UTC)
- Subject: Fix PR c/39613 (case labels and integer constant expressions)
This patch fixes PR 39613, where a case label that is not an integer
constant expression but folds to an integer constant is now rejected,
causing the Linux kernel to fail to compile. This rejection is
correct for ISO C, but to let the kernel continue to compile this
patch arranges for this case to have a pedwarn-if-pedantic instead of
a mandatory hard error. (Some parts of constant expressions semantics
can't depend on -pedantic because the correct semantics are required
for valid programs to be accepted, not just for invalid ones to be
rejected. This issue can however depend on -pedantic because it's
purely a matter of how some invalid programs are handled.)
Bootstrapped with no regressions on i686-pc-linux-gnu. Applied to
mainline.
2009-04-09 Joseph Myers <joseph@codesourcery.com>
PR c/39613
* c-typeck.c (do_case): If case label is not an INTEGER_CST, fold
it and pedwarn if this results in an INTEGER_CST.
testsuite:
2009-04-09 Joseph Myers <joseph@codesourcery.com>
PR c/39613
* gcc.dg/case-const-1.c, gcc.dg/case-const-2.c,
gcc.dg/case-const-3.c: New tests.
Index: testsuite/gcc.dg/case-const-2.c
===================================================================
--- testsuite/gcc.dg/case-const-2.c (revision 0)
+++ testsuite/gcc.dg/case-const-2.c (revision 0)
@@ -0,0 +1,15 @@
+/* Test for case labels not integer constant expressions but folding
+ to integer constants (used in Linux kernel, PR 39613). */
+/* { dg-do compile } */
+/* { dg-options "-pedantic" } */
+
+extern int i;
+void
+f (int c)
+{
+ switch (c)
+ {
+ case (1 ? 1 : i): /* { dg-warning "case label is not an integer constant expression" } */
+ ;
+ }
+}
Index: testsuite/gcc.dg/case-const-1.c
===================================================================
--- testsuite/gcc.dg/case-const-1.c (revision 0)
+++ testsuite/gcc.dg/case-const-1.c (revision 0)
@@ -0,0 +1,15 @@
+/* Test for case labels not integer constant expressions but folding
+ to integer constants (used in Linux kernel, PR 39613). */
+/* { dg-do compile } */
+/* { dg-options "" } */
+
+extern int i;
+void
+f (int c)
+{
+ switch (c)
+ {
+ case (1 ? 1 : i):
+ ;
+ }
+}
Index: testsuite/gcc.dg/case-const-3.c
===================================================================
--- testsuite/gcc.dg/case-const-3.c (revision 0)
+++ testsuite/gcc.dg/case-const-3.c (revision 0)
@@ -0,0 +1,15 @@
+/* Test for case labels not integer constant expressions but folding
+ to integer constants (used in Linux kernel, PR 39613). */
+/* { dg-do compile } */
+/* { dg-options "-pedantic-errors" } */
+
+extern int i;
+void
+f (int c)
+{
+ switch (c)
+ {
+ case (1 ? 1 : i): /* { dg-error "case label is not an integer constant expression" } */
+ ;
+ }
+}
Index: c-typeck.c
===================================================================
--- c-typeck.c (revision 145737)
+++ c-typeck.c (working copy)
@@ -7851,6 +7851,22 @@ do_case (tree low_value, tree high_value
{
tree label = NULL_TREE;
+ if (low_value && TREE_CODE (low_value) != INTEGER_CST)
+ {
+ low_value = c_fully_fold (low_value, false, NULL);
+ if (TREE_CODE (low_value) == INTEGER_CST)
+ pedwarn (input_location, OPT_pedantic,
+ "case label is not an integer constant expression");
+ }
+
+ if (high_value && TREE_CODE (high_value) != INTEGER_CST)
+ {
+ high_value = c_fully_fold (high_value, false, NULL);
+ if (TREE_CODE (high_value) == INTEGER_CST)
+ pedwarn (input_location, OPT_pedantic,
+ "case label is not an integer constant expression");
+ }
+
if (c_switch_stack && !c_switch_stack->blocked_stmt_expr
&& !c_switch_stack->blocked_vm)
{
--
Joseph S. Myers
joseph@codesourcery.com