aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Polacek <polacek@redhat.com>2015-05-07 19:36:31 +0000
committerMarek Polacek <mpolacek@gcc.gnu.org>2015-05-07 19:36:31 +0000
commit0173bd2a038cbeef871b22b312a6856ab1dcda2a (patch)
tree12367850915ce482968be36f7c2f4344d74b5ed5
parentd57c99458933a21fdf94f508191f145ad8d5ec58 (diff)
downloadgcc-0173bd2a038cbeef871b22b312a6856ab1dcda2a.zip
gcc-0173bd2a038cbeef871b22b312a6856ab1dcda2a.tar.gz
gcc-0173bd2a038cbeef871b22b312a6856ab1dcda2a.tar.bz2
re PR c/65179 (Introduce new C warning: -Wshift-negative-value)
PR c/65179 * c-common.c (c_fully_fold_internal): Warn when left shifting a negative value. * c.opt (Wshift-negative-value): New option. * c-opts.c (c_common_post_options): Set warn_shift_negative_value when -Wextra and C99/C++11 mode. * c-typeck.c (build_binary_op): Warn when left shifting a negative value. * typeck.c (cp_build_binary_op): Warn when left shifting a negative value. * doc/invoke.texi: Document -Wshift-negative-value. * c-c++-common/Wshift-negative-value-1.c: New test. * testsuite/c-c++-common/Wshift-negative-value-2.c: New test. * testsuite/c-c++-common/Wshift-negative-value-3.c: New test. * testsuite/c-c++-common/Wshift-negative-value-4.c: New test. * testsuite/c-c++-common/Wshift-negative-value-5.c: New test. * testsuite/c-c++-common/Wshift-negative-value-6.c: New test. * testsuite/gcc.dg/c90-left-shift-1.c: New test. * testsuite/gcc.dg/c99-const-expr-7.c: Add dg-error. * testsuite/gcc.dg/c99-left-shift-1.c: New test. From-SVN: r222889
-rw-r--r--gcc/ChangeLog5
-rw-r--r--gcc/c-family/ChangeLog9
-rw-r--r--gcc/c-family/c-common.c8
-rw-r--r--gcc/c-family/c-opts.c5
-rw-r--r--gcc/c-family/c.opt4
-rw-r--r--gcc/c/ChangeLog6
-rw-r--r--gcc/c/c-typeck.c11
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/typeck.c9
-rw-r--r--gcc/doc/invoke.texi9
-rw-r--r--gcc/testsuite/ChangeLog13
-rw-r--r--gcc/testsuite/c-c++-common/Wshift-negative-value-1.c49
-rw-r--r--gcc/testsuite/c-c++-common/Wshift-negative-value-2.c49
-rw-r--r--gcc/testsuite/c-c++-common/Wshift-negative-value-3.c49
-rw-r--r--gcc/testsuite/c-c++-common/Wshift-negative-value-4.c49
-rw-r--r--gcc/testsuite/c-c++-common/Wshift-negative-value-5.c50
-rw-r--r--gcc/testsuite/c-c++-common/Wshift-negative-value-6.c50
-rw-r--r--gcc/testsuite/gcc.dg/c90-left-shift-1.c12
-rw-r--r--gcc/testsuite/gcc.dg/c99-const-expr-7.c2
-rw-r--r--gcc/testsuite/gcc.dg/c99-left-shift-1.c12
20 files changed, 405 insertions, 2 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f973501..f1c685a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,8 @@
+2015-05-07 Marek Polacek <polacek@redhat.com>
+
+ PR c/65179
+ * doc/invoke.texi: Document -Wshift-negative-value.
+
2015-05-06 Aditya Kumar <hiraditya@msn.com>
* gcov-tool.c (do_merge): Refactore to remove int ret.
diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog
index dd69f25..6f14121 100644
--- a/gcc/c-family/ChangeLog
+++ b/gcc/c-family/ChangeLog
@@ -1,4 +1,13 @@
2015-05-07 Marek Polacek <polacek@redhat.com>
+
+ PR c/65179
+ * c-common.c (c_fully_fold_internal): Warn when left shifting a
+ negative value.
+ * c.opt (Wshift-negative-value): New option.
+ * c-opts.c (c_common_post_options): Set warn_shift_negative_value
+ when -Wextra and C99/C++11 mode.
+
+2015-05-07 Marek Polacek <polacek@redhat.com>
Martin Uecker <uecker@eecs.berkeley.edu>
* c-ubsan.c (ubsan_instrument_bounds): Don't skip instrumenting
diff --git a/gcc/c-family/c-common.c b/gcc/c-family/c-common.c
index ada8e8a..378f237 100644
--- a/gcc/c-family/c-common.c
+++ b/gcc/c-family/c-common.c
@@ -1361,6 +1361,14 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
&& !TREE_OVERFLOW_P (op0)
&& !TREE_OVERFLOW_P (op1))
overflow_warning (EXPR_LOCATION (expr), ret);
+ if (code == LSHIFT_EXPR
+ && TREE_CODE (orig_op0) != INTEGER_CST
+ && TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
+ && TREE_CODE (op0) == INTEGER_CST
+ && c_inhibit_evaluation_warnings == 0
+ && tree_int_cst_sgn (op0) < 0)
+ warning_at (loc, OPT_Wshift_negative_value,
+ "left shift of negative value");
if ((code == LSHIFT_EXPR || code == RSHIFT_EXPR)
&& TREE_CODE (orig_op1) != INTEGER_CST
&& TREE_CODE (op1) == INTEGER_CST
diff --git a/gcc/c-family/c-opts.c b/gcc/c-family/c-opts.c
index 1a67b5a..a61d6a8 100644
--- a/gcc/c-family/c-opts.c
+++ b/gcc/c-family/c-opts.c
@@ -866,6 +866,11 @@ c_common_post_options (const char **pfilename)
if (warn_implicit_int == -1)
warn_implicit_int = flag_isoc99;
+ /* -Wshift-negative-value is enabled by -Wextra in C99 and C++11 modes. */
+ if (warn_shift_negative_value == -1)
+ warn_shift_negative_value = (extra_warnings
+ && (cxx_dialect >= cxx11 || flag_isoc99));
+
/* Declone C++ 'structors if -Os. */
if (flag_declone_ctor_dtor == -1)
flag_declone_ctor_dtor = optimize_size;
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 8ef0cea..48947b4 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -781,6 +781,10 @@ Wshift-count-overflow
C ObjC C++ ObjC++ Var(warn_shift_count_overflow) Init(1) Warning
Warn if shift count >= width of type
+Wshift-negative-value
+C ObjC C++ ObjC++ Var(warn_shift_negative_value) Init(-1) Warning
+Warn if left shifting a negative value
+
Wsign-compare
C ObjC C++ ObjC++ Var(warn_sign_compare) Warning LangEnabledBy(C++ ObjC++,Wall)
Warn about signed-unsigned comparisons
diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog
index 2ef895a..ccd1e72 100644
--- a/gcc/c/ChangeLog
+++ b/gcc/c/ChangeLog
@@ -1,3 +1,9 @@
+2015-05-07 Marek Polacek <polacek@redhat.com>
+
+ PR c/65179
+ * c-typeck.c (build_binary_op): Warn when left shifting a negative
+ value.
+
2015-04-30 Marek Polacek <polacek@redhat.com>
* c-typeck.c (set_init_label): Call error_at instead of error and
diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c
index 328f294..73275aa 100644
--- a/gcc/c/c-typeck.c
+++ b/gcc/c/c-typeck.c
@@ -10697,6 +10697,17 @@ build_binary_op (location_t location, enum tree_code code,
&& code1 == INTEGER_TYPE)
{
doing_shift = true;
+ if (TREE_CODE (op0) == INTEGER_CST
+ && tree_int_cst_sgn (op0) < 0)
+ {
+ /* Don't reject a left shift of a negative value in a context
+ where a constant expression is needed in C90. */
+ if (flag_isoc99)
+ int_const = false;
+ if (c_inhibit_evaluation_warnings == 0)
+ warning_at (location, OPT_Wshift_negative_value,
+ "left shift of negative value");
+ }
if (TREE_CODE (op1) == INTEGER_CST)
{
if (tree_int_cst_sgn (op1) < 0)
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 4929faa..3c32e6f 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2015-05-07 Marek Polacek <polacek@redhat.com>
+
+ PR c/65179
+ * typeck.c (cp_build_binary_op): Warn when left shifting a negative
+ value.
+
2015-05-07 Jason Merrill <jason@redhat.com>
DR 1467
diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 91db32a..549e4b1 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -4326,11 +4326,20 @@ cp_build_binary_op (location_t location,
}
else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE)
{
+ tree const_op0 = fold_non_dependent_expr (op0);
+ if (TREE_CODE (const_op0) != INTEGER_CST)
+ const_op0 = op0;
tree const_op1 = fold_non_dependent_expr (op1);
if (TREE_CODE (const_op1) != INTEGER_CST)
const_op1 = op1;
result_type = type0;
doing_shift = true;
+ if (TREE_CODE (const_op0) == INTEGER_CST
+ && tree_int_cst_sgn (const_op0) < 0
+ && (complain & tf_warning)
+ && c_inhibit_evaluation_warnings == 0)
+ warning (OPT_Wshift_negative_value,
+ "left shift of negative value");
if (TREE_CODE (const_op1) == INTEGER_CST)
{
if (tree_int_cst_lt (const_op1, integer_zero_node))
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 2c58a0d..934edd6 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -271,7 +271,7 @@ Objective-C and Objective-C++ Dialects}.
-Wpointer-arith -Wno-pointer-to-int-cast @gol
-Wredundant-decls -Wno-return-local-addr @gol
-Wreturn-type -Wsequence-point -Wshadow -Wno-shadow-ivar @gol
--Wshift-count-negative -Wshift-count-overflow @gol
+-Wshift-count-negative -Wshift-count-overflow -Wshift-negative-value @gol
-Wsign-compare -Wsign-conversion -Wfloat-conversion @gol
-Wsizeof-pointer-memaccess -Wsizeof-array-argument @gol
-Wstack-protector -Wstack-usage=@var{len} -Wstrict-aliasing @gol
@@ -3489,6 +3489,7 @@ name is still supported, but the newer name is more descriptive.)
-Wsign-compare @gol
-Wtype-limits @gol
-Wuninitialized @gol
+-Wshift-negative-value @gol
-Wunused-parameter @r{(only with} @option{-Wunused} @r{or} @option{-Wall}@r{)} @gol
-Wunused-but-set-parameter @r{(only with} @option{-Wunused} @r{or} @option{-Wall}@r{)} @gol
}
@@ -3922,6 +3923,12 @@ Warn if shift count is negative. This warning is enabled by default.
@opindex Wno-shift-count-overflow
Warn if shift count >= width of type. This warning is enabled by default.
+@item -Wshift-negative-value
+@opindex Wshift-negative-value
+@opindex Wno-shift-negative-value
+Warn if left shifting a negative value. This warning is enabled by
+@option{-Wextra} in C99 and C++11 modes (and newer).
+
@item -Wswitch
@opindex Wswitch
@opindex Wno-switch
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1bacc3e..4ffc428 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,16 @@
+2015-05-07 Marek Polacek <polacek@redhat.com>
+
+ PR c/65179
+ * c-c++-common/Wshift-negative-value-1.c: New test.
+ * testsuite/c-c++-common/Wshift-negative-value-2.c: New test.
+ * testsuite/c-c++-common/Wshift-negative-value-3.c: New test.
+ * testsuite/c-c++-common/Wshift-negative-value-4.c: New test.
+ * testsuite/c-c++-common/Wshift-negative-value-5.c: New test.
+ * testsuite/c-c++-common/Wshift-negative-value-6.c: New test.
+ * testsuite/gcc.dg/c90-left-shift-1.c: New test.
+ * testsuite/gcc.dg/c99-const-expr-7.c: Add dg-error.
+ * testsuite/gcc.dg/c99-left-shift-1.c: New test.
+
2015-05-07 Segher Boessenkool <segher@kernel.crashing.org>
PR middle-end/192
diff --git a/gcc/testsuite/c-c++-common/Wshift-negative-value-1.c b/gcc/testsuite/c-c++-common/Wshift-negative-value-1.c
new file mode 100644
index 0000000..5d803ad
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wshift-negative-value-1.c
@@ -0,0 +1,49 @@
+/* PR c/65179 */
+/* { dg-do compile } */
+/* { dg-options "-O -Wextra" } */
+/* { dg-additional-options "-std=c++11" { target c++ } } */
+
+enum E {
+ A = 0 << 1,
+ B = 1 << 1,
+ C = -1 << 1, /* { dg-warning "left shift of negative value|not an integer constant" } */
+ D = 0 >> 1,
+ E = 1 >> 1,
+ F = -1 >> 1
+};
+
+int
+left (int x)
+{
+ /* Warn for LSHIFT_EXPR. */
+ const int z = 0;
+ const int o = 1;
+ const int m = -1;
+ int r = 0;
+ r += z << x;
+ r += o << x;
+ r += m << x; /* { dg-warning "left shift of negative value" } */
+ r += 0 << x;
+ r += 1 << x;
+ r += -1 << x; /* { dg-warning "left shift of negative value" } */
+ r += -1U << x;
+ return r;
+}
+
+int
+right (int x)
+{
+ /* Shouldn't warn for RSHIFT_EXPR. */
+ const int z = 0;
+ const int o = 1;
+ const int m = -1;
+ int r = 0;
+ r += z >> x;
+ r += o >> x;
+ r += m >> x;
+ r += 0 >> x;
+ r += 1 >> x;
+ r += -1 >> x;
+ r += -1U >> x;
+ return r;
+}
diff --git a/gcc/testsuite/c-c++-common/Wshift-negative-value-2.c b/gcc/testsuite/c-c++-common/Wshift-negative-value-2.c
new file mode 100644
index 0000000..fc89af1
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wshift-negative-value-2.c
@@ -0,0 +1,49 @@
+/* PR c/65179 */
+/* { dg-do compile } */
+/* { dg-options "-O -Wshift-negative-value" } */
+/* { dg-additional-options "-std=c++11" { target c++ } } */
+
+enum E {
+ A = 0 << 1,
+ B = 1 << 1,
+ C = -1 << 1, /* { dg-warning "left shift of negative value" } */
+ D = 0 >> 1,
+ E = 1 >> 1,
+ F = -1 >> 1
+};
+
+int
+left (int x)
+{
+ /* Warn for LSHIFT_EXPR. */
+ const int z = 0;
+ const int o = 1;
+ const int m = -1;
+ int r = 0;
+ r += z << x;
+ r += o << x;
+ r += m << x; /* { dg-warning "left shift of negative value" } */
+ r += 0 << x;
+ r += 1 << x;
+ r += -1 << x; /* { dg-warning "left shift of negative value" } */
+ r += -1U << x;
+ return r;
+}
+
+int
+right (int x)
+{
+ /* Shouldn't warn for RSHIFT_EXPR. */
+ const int z = 0;
+ const int o = 1;
+ const int m = -1;
+ int r = 0;
+ r += z >> x;
+ r += o >> x;
+ r += m >> x;
+ r += 0 >> x;
+ r += 1 >> x;
+ r += -1 >> x;
+ r += -1U >> x;
+ return r;
+}
diff --git a/gcc/testsuite/c-c++-common/Wshift-negative-value-3.c b/gcc/testsuite/c-c++-common/Wshift-negative-value-3.c
new file mode 100644
index 0000000..bf9b1a0
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wshift-negative-value-3.c
@@ -0,0 +1,49 @@
+/* PR c/65179 */
+/* { dg-do compile } */
+/* { dg-options "-O -Wextra -Wno-shift-negative-value" } */
+/* { dg-additional-options "-std=c++11" { target c++ } } */
+
+enum E {
+ A = 0 << 1,
+ B = 1 << 1,
+ C = -1 << 1,
+ D = 0 >> 1,
+ E = 1 >> 1,
+ F = -1 >> 1
+};
+
+int
+left (int x)
+{
+ /* Warn for LSHIFT_EXPR. */
+ const int z = 0;
+ const int o = 1;
+ const int m = -1;
+ int r = 0;
+ r += z << x;
+ r += o << x;
+ r += m << x; /* { dg-bogus "left shift of negative value" } */
+ r += 0 << x;
+ r += 1 << x;
+ r += -1 << x; /* { dg-bogus "left shift of negative value" } */
+ r += -1U << x;
+ return r;
+}
+
+int
+right (int x)
+{
+ /* Shouldn't warn for RSHIFT_EXPR. */
+ const int z = 0;
+ const int o = 1;
+ const int m = -1;
+ int r = 0;
+ r += z >> x;
+ r += o >> x;
+ r += m >> x;
+ r += 0 >> x;
+ r += 1 >> x;
+ r += -1 >> x;
+ r += -1U >> x;
+ return r;
+}
diff --git a/gcc/testsuite/c-c++-common/Wshift-negative-value-4.c b/gcc/testsuite/c-c++-common/Wshift-negative-value-4.c
new file mode 100644
index 0000000..85fbd0e
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wshift-negative-value-4.c
@@ -0,0 +1,49 @@
+/* PR c/65179 */
+/* { dg-do compile } */
+/* { dg-options "-O" } */
+/* { dg-additional-options "-std=c++11" { target c++ } } */
+
+enum E {
+ A = 0 << 1,
+ B = 1 << 1,
+ C = -1 << 1,
+ D = 0 >> 1,
+ E = 1 >> 1,
+ F = -1 >> 1
+};
+
+int
+left (int x)
+{
+ /* Warn for LSHIFT_EXPR. */
+ const int z = 0;
+ const int o = 1;
+ const int m = -1;
+ int r = 0;
+ r += z << x;
+ r += o << x;
+ r += m << x; /* { dg-bogus "left shift of negative value" } */
+ r += 0 << x;
+ r += 1 << x;
+ r += -1 << x; /* { dg-bogus "left shift of negative value" } */
+ r += -1U << x;
+ return r;
+}
+
+int
+right (int x)
+{
+ /* Shouldn't warn for RSHIFT_EXPR. */
+ const int z = 0;
+ const int o = 1;
+ const int m = -1;
+ int r = 0;
+ r += z >> x;
+ r += o >> x;
+ r += m >> x;
+ r += 0 >> x;
+ r += 1 >> x;
+ r += -1 >> x;
+ r += -1U >> x;
+ return r;
+}
diff --git a/gcc/testsuite/c-c++-common/Wshift-negative-value-5.c b/gcc/testsuite/c-c++-common/Wshift-negative-value-5.c
new file mode 100644
index 0000000..74ecd1e
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wshift-negative-value-5.c
@@ -0,0 +1,50 @@
+/* PR c/65179 */
+/* { dg-do compile } */
+/* { dg-options "-O -Wshift-negative-value" } */
+/* { dg-additional-options "-std=c++03" { target c++ } } */
+/* { dg-additional-options "-std=c90" { target c } } */
+
+enum E {
+ A = 0 << 1,
+ B = 1 << 1,
+ C = -1 << 1, /* { dg-warning "left shift of negative value" } */
+ D = 0 >> 1,
+ E = 1 >> 1,
+ F = -1 >> 1
+};
+
+int
+left (int x)
+{
+ /* Warn for LSHIFT_EXPR. */
+ const int z = 0;
+ const int o = 1;
+ const int m = -1;
+ int r = 0;
+ r += z << x;
+ r += o << x;
+ r += m << x; /* { dg-warning "left shift of negative value" } */
+ r += 0 << x;
+ r += 1 << x;
+ r += -1 << x; /* { dg-warning "left shift of negative value" } */
+ r += -1U << x;
+ return r;
+}
+
+int
+right (int x)
+{
+ /* Shouldn't warn for RSHIFT_EXPR. */
+ const int z = 0;
+ const int o = 1;
+ const int m = -1;
+ int r = 0;
+ r += z >> x;
+ r += o >> x;
+ r += m >> x;
+ r += 0 >> x;
+ r += 1 >> x;
+ r += -1 >> x;
+ r += -1U >> x;
+ return r;
+}
diff --git a/gcc/testsuite/c-c++-common/Wshift-negative-value-6.c b/gcc/testsuite/c-c++-common/Wshift-negative-value-6.c
new file mode 100644
index 0000000..de9db52
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/Wshift-negative-value-6.c
@@ -0,0 +1,50 @@
+/* PR c/65179 */
+/* { dg-do compile } */
+/* { dg-options "-O -Wextra" } */
+/* { dg-additional-options "-std=c++03" { target c++ } } */
+/* { dg-additional-options "-std=c90" { target c } } */
+
+enum E {
+ A = 0 << 1,
+ B = 1 << 1,
+ C = -1 << 1, /* { dg-bogus "left shift of negative value" } */
+ D = 0 >> 1,
+ E = 1 >> 1,
+ F = -1 >> 1
+};
+
+int
+left (int x)
+{
+ /* Warn for LSHIFT_EXPR. */
+ const int z = 0;
+ const int o = 1;
+ const int m = -1;
+ int r = 0;
+ r += z << x;
+ r += o << x;
+ r += m << x; /* { dg-bogus "left shift of negative value" } */
+ r += 0 << x;
+ r += 1 << x;
+ r += -1 << x; /* { dg-bogus "left shift of negative value" } */
+ r += -1U << x;
+ return r;
+}
+
+int
+right (int x)
+{
+ /* Shouldn't warn for RSHIFT_EXPR. */
+ const int z = 0;
+ const int o = 1;
+ const int m = -1;
+ int r = 0;
+ r += z >> x;
+ r += o >> x;
+ r += m >> x;
+ r += 0 >> x;
+ r += 1 >> x;
+ r += -1 >> x;
+ r += -1U >> x;
+ return r;
+}
diff --git a/gcc/testsuite/gcc.dg/c90-left-shift-1.c b/gcc/testsuite/gcc.dg/c90-left-shift-1.c
new file mode 100644
index 0000000..755595f
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c90-left-shift-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1990 -pedantic-errors" } */
+
+enum E { A = -2 << 1 };
+int i = -1 << 0;
+
+int
+f (int i)
+{
+ switch (i)
+ case -1 << 0: break;
+}
diff --git a/gcc/testsuite/gcc.dg/c99-const-expr-7.c b/gcc/testsuite/gcc.dg/c99-const-expr-7.c
index b872077..75b05677 100644
--- a/gcc/testsuite/gcc.dg/c99-const-expr-7.c
+++ b/gcc/testsuite/gcc.dg/c99-const-expr-7.c
@@ -30,8 +30,8 @@ int f1 = (0 ? 0 << -1 : 0);
int g1 = (0 ? 0 >> 1000 : 0);
int h1 = (0 ? 0 >> -1: 0);
-/* Allowed for now, but actually undefined behavior in C99. */
int i = -1 << 0;
+/* { dg-error "constant" "constant" { target *-*-* } 33 } */
int j[1] = { DBL_MAX }; /* { dg-warning "overflow in implicit constant conversion" } */
/* { dg-error "overflow in constant expression" "constant" { target *-*-* } 36 } */
diff --git a/gcc/testsuite/gcc.dg/c99-left-shift-1.c b/gcc/testsuite/gcc.dg/c99-left-shift-1.c
new file mode 100644
index 0000000..9a73049
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/c99-left-shift-1.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+/* { dg-options "-std=iso9899:1999 -pedantic-errors" } */
+
+enum E { A = -2 << 1 }; /* { dg-error "constant expression" } */
+int i = -1 << 0; /* { dg-error "constant expression" } */
+
+int
+f (int i)
+{
+ switch (i)
+ case -1 << 0: break; /* { dg-error "constant expression" } */
+}