c, c++, c-family: -Wshift-negative-value and -Wshift-overflow* tweaks for -fwrapv...
authorJakub Jelinek <jakub@redhat.com>
Wed, 9 Mar 2022 08:15:28 +0000 (09:15 +0100)
committerJakub Jelinek <jakub@redhat.com>
Wed, 9 Mar 2022 08:15:28 +0000 (09:15 +0100)
As mentioned in the PR, different standards have different definition
on what is an UB left shift.  They all agree on out of bounds (including
negative) shift count.
The rules used by ubsan are:
C99-C2x ((unsigned) x >> (uprecm1 - y)) != 0 then UB
C++11-C++17 x < 0 || ((unsigned) x >> (uprecm1 - y)) > 1 then UB
C++20 and later everything is well defined
Now, for C++20, I've in the P1236R1 implementation added an early
exit for -Wshift-overflow* warning so that it never warns, but apparently
-Wshift-negative-value remained as is.  As it is well defined in C++20,
the following patch doesn't enable -Wshift-negative-value from -Wextra
anymore for C++20 and later, if users want for compatibility with C++17
and earlier get the warning, they still can by using -Wshift-negative-value
explicitly.
Another thing is -fwrapv, that is an extension to the standards, so it is up
to us how exactly we define that case.  Our ubsan code treats
TYPE_OVERFLOW_WRAPS (type0) and cxx_dialect >= cxx20 the same as only
diagnosing out of bounds shift count and nothing else and IMHO it is most
sensical to treat -fwrapv signed left shifts the same as C++20 treats
them, https://eel.is/c++draft/expr.shift#2
"The value of E1 << E2 is the unique value congruent to E1×2^E2 modulo 2^N,
where N is the width of the type of the result.
[Note 1: E1 is left-shifted E2 bit positions; vacated bits are zero-filled.
— end note]"
with no UB dependent on the E1 values.  The UB is only
"The behavior is undefined if the right operand is negative, or greater
than or equal to the width of the promoted left operand."
Under the hood (except for FEs and ubsan from FEs) GCC middle-end doesn't
consider UB in left shifts dependent on the first operand's value, only
the out of bounds shifts.

While this change isn't a regression, I'd think it is useful for GCC 12,
it doesn't add new warnings, but just removes warnings that aren't
appropriate.

2022-03-09  Jakub Jelinek  <jakub@redhat.com>

PR c/104711
gcc/
* doc/invoke.texi (-Wextra): Document that -Wshift-negative-value
is enabled by it only for C++11 to C++17 rather than for C++03 or
later.
(-Wshift-negative-value): Similarly (except here we stated
that it is enabled for C++11 or later).
gcc/c-family/
* c-opts.cc (c_common_post_options): Don't enable
-Wshift-negative-value from -Wextra for C++20 or later.
* c-ubsan.cc (ubsan_instrument_shift): Adjust comments.
* c-warn.cc (maybe_warn_shift_overflow): Use TYPE_OVERFLOW_WRAPS
instead of TYPE_UNSIGNED.
gcc/c/
* c-fold.cc (c_fully_fold_internal): Don't emit
-Wshift-negative-value warning if TYPE_OVERFLOW_WRAPS.
* c-typeck.cc (build_binary_op): Likewise.
gcc/cp/
* constexpr.cc (cxx_eval_check_shift_p): Use TYPE_OVERFLOW_WRAPS
instead of TYPE_UNSIGNED.
* typeck.cc (cp_build_binary_op): Don't emit
-Wshift-negative-value warning if TYPE_OVERFLOW_WRAPS.
gcc/testsuite/
* c-c++-common/Wshift-negative-value-1.c: Remove
dg-additional-options, instead in target selectors of each diagnostic
check for exact C++ versions where it should be diagnosed.
* c-c++-common/Wshift-negative-value-2.c: Likewise.
* c-c++-common/Wshift-negative-value-3.c: Likewise.
* c-c++-common/Wshift-negative-value-4.c: Likewise.
* c-c++-common/Wshift-negative-value-7.c: New test.
* c-c++-common/Wshift-negative-value-8.c: New test.
* c-c++-common/Wshift-negative-value-9.c: New test.
* c-c++-common/Wshift-negative-value-10.c: New test.
* c-c++-common/Wshift-overflow-1.c: Remove
dg-additional-options, instead in target selectors of each diagnostic
check for exact C++ versions where it should be diagnosed.
* c-c++-common/Wshift-overflow-2.c: Likewise.
* c-c++-common/Wshift-overflow-5.c: Likewise.
* c-c++-common/Wshift-overflow-6.c: Likewise.
* c-c++-common/Wshift-overflow-7.c: Likewise.
* c-c++-common/Wshift-overflow-8.c: New test.
* c-c++-common/Wshift-overflow-9.c: New test.
* c-c++-common/Wshift-overflow-10.c: New test.
* c-c++-common/Wshift-overflow-11.c: New test.
* c-c++-common/Wshift-overflow-12.c: New test.

26 files changed:
gcc/c-family/c-opts.cc
gcc/c-family/c-ubsan.cc
gcc/c-family/c-warn.cc
gcc/c/c-fold.cc
gcc/c/c-typeck.cc
gcc/cp/constexpr.cc
gcc/cp/typeck.cc
gcc/doc/invoke.texi
gcc/testsuite/c-c++-common/Wshift-negative-value-1.c
gcc/testsuite/c-c++-common/Wshift-negative-value-10.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/Wshift-negative-value-2.c
gcc/testsuite/c-c++-common/Wshift-negative-value-3.c
gcc/testsuite/c-c++-common/Wshift-negative-value-4.c
gcc/testsuite/c-c++-common/Wshift-negative-value-7.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/Wshift-negative-value-8.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/Wshift-negative-value-9.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/Wshift-overflow-1.c
gcc/testsuite/c-c++-common/Wshift-overflow-10.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/Wshift-overflow-11.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/Wshift-overflow-12.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/Wshift-overflow-2.c
gcc/testsuite/c-c++-common/Wshift-overflow-5.c
gcc/testsuite/c-c++-common/Wshift-overflow-6.c
gcc/testsuite/c-c++-common/Wshift-overflow-7.c
gcc/testsuite/c-c++-common/Wshift-overflow-8.c [new file with mode: 0644]
gcc/testsuite/c-c++-common/Wshift-overflow-9.c [new file with mode: 0644]

index 21ff22d1b4fbd76a316c60653b961c880cde7e31..a341a061758d4ff69abddf2dca4f9f12a53d990b 100644 (file)
@@ -934,10 +934,12 @@ c_common_post_options (const char **pfilename)
   if (warn_shift_overflow == -1)
     warn_shift_overflow = cxx_dialect >= cxx11 || flag_isoc99;
 
-  /* -Wshift-negative-value is enabled by -Wextra in C99 and C++11 modes.  */
+  /* -Wshift-negative-value is enabled by -Wextra in C99 and C++11 to C++17
+     modes.  */
   if (warn_shift_negative_value == -1)
     warn_shift_negative_value = (extra_warnings
-                                && (cxx_dialect >= cxx11 || flag_isoc99));
+                                && (cxx_dialect >= cxx11 || flag_isoc99)
+                                && cxx_dialect < cxx20);
 
   /* -Wregister is enabled by default in C++17.  */
   SET_OPTION_IF_UNSET (&global_options, &global_options_set, warn_register,
index 7fe49561a5c99f17c3af2071b791f1d8bad5c657..48f948745f8b00c3028f99cdf828f2082d101aca 100644 (file)
@@ -173,7 +173,7 @@ ubsan_instrument_shift (location_t loc, enum tree_code code,
       || cxx_dialect >= cxx20)
     ;
 
-  /* For signed x << y, in C99/C11, the following:
+  /* For signed x << y, in C99 and later, the following:
      (unsigned) x >> (uprecm1 - y)
      if non-zero, is undefined.  */
   else if (code == LSHIFT_EXPR && flag_isoc99 && cxx_dialect < cxx11)
@@ -186,7 +186,7 @@ ubsan_instrument_shift (location_t loc, enum tree_code code,
                        build_int_cst (TREE_TYPE (tt), 0));
     }
 
-  /* For signed x << y, in C++11 and later, the following:
+  /* For signed x << y, in C++11 to C++17, the following:
      x < 0 || ((unsigned) x >> (uprecm1 - y))
      if > 1, is undefined.  */
   else if (code == LSHIFT_EXPR && cxx_dialect >= cxx11)
index 1ce2202c7ff6d218dba35083e48c2f6c17884024..9025fc1c20eb6732afb2c7f51d9e58d515bdf96c 100644 (file)
@@ -2605,7 +2605,7 @@ maybe_warn_shift_overflow (location_t loc, tree op0, tree op1)
   unsigned int prec0 = TYPE_PRECISION (type0);
 
   /* Left-hand operand must be signed.  */
-  if (TYPE_UNSIGNED (type0) || cxx_dialect >= cxx20)
+  if (TYPE_OVERFLOW_WRAPS (type0) || cxx_dialect >= cxx20)
     return false;
 
   unsigned int min_prec = (wi::min_precision (wi::to_wide (op0), SIGNED)
index 76ea25b3d7febeda3b1b65b4656a0e43f9d7ad60..ac4ceaac2906e2076b7bafa052a5f613f46d54ca 100644 (file)
@@ -382,6 +382,7 @@ c_fully_fold_internal (tree expr, bool in_init, bool *maybe_const_operands,
          && TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE
          && TREE_CODE (op0) == INTEGER_CST
          && c_inhibit_evaluation_warnings == 0
+         && !TYPE_OVERFLOW_WRAPS (TREE_TYPE (orig_op0))
          && tree_int_cst_sgn (op0) < 0)
        warning_at (loc, OPT_Wshift_negative_value,
                    "left shift of negative value");
index 3075c8835483251180977efad27a16881986addb..b37f3cfcd8be72f9b3df8c9cdf1b0a1613e299cc 100644 (file)
@@ -12213,7 +12213,8 @@ build_binary_op (location_t location, enum tree_code code,
        {
          doing_shift = true;
          if (TREE_CODE (op0) == INTEGER_CST
-             && tree_int_cst_sgn (op0) < 0)
+             && tree_int_cst_sgn (op0) < 0
+             && !TYPE_OVERFLOW_WRAPS (type0))
            {
              /* Don't reject a left shift of a negative value in a context
                 where a constant expression is needed in C90.  */
index 4716694cb710a946d25323e5e8725e4bfbca56a3..388957913bed7220e1b5893faa0be6d239d7d0fa 100644 (file)
@@ -3165,7 +3165,7 @@ cxx_eval_check_shift_p (location_t loc, const constexpr_ctx *ctx,
      The value of E1 << E2 is the unique value congruent to E1 x 2^E2 modulo
      2^N, where N is the range exponent of the type of the result.  */
   if (code == LSHIFT_EXPR
-      && !TYPE_UNSIGNED (lhstype)
+      && !TYPE_OVERFLOW_WRAPS (lhstype)
       && cxx_dialect >= cxx11
       && cxx_dialect < cxx20)
     {
index ea6a485bbbf65055872340857a3173239ce4a8f0..516fa574ef63525478e2c0a70825c989f70265fa 100644 (file)
@@ -5382,6 +5382,7 @@ cp_build_binary_op (const op_location_t &location,
          doing_shift = true;
          if (TREE_CODE (const_op0) == INTEGER_CST
              && tree_int_cst_sgn (const_op0) < 0
+             && !TYPE_OVERFLOW_WRAPS (type0)
              && (complain & tf_warning)
              && c_inhibit_evaluation_warnings == 0)
            warning_at (location, OPT_Wshift_negative_value,
index a0fa5e1cf434202b6832d7f289f41b6251ce076d..036e1f0c32bc3c92f9b26e302f582eb45cf0ec7f 100644 (file)
@@ -5809,7 +5809,7 @@ name is still supported, but the newer name is more descriptive.)
 -Wredundant-move @r{(only for C++)}  @gol
 -Wtype-limits  @gol
 -Wuninitialized  @gol
--Wshift-negative-value @r{(in C++03 and in C99 and newer)}  @gol
+-Wshift-negative-value @r{(in C++11 to C++17 and in C99 and newer)}  @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{)}}
 
@@ -6839,7 +6839,7 @@ of the type.  This warning is enabled by default.
 @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).
+@option{-Wextra} in C99 (and newer) and C++11 to C++17 modes.
 
 @item -Wno-shift-overflow
 @itemx -Wshift-overflow=@var{n}
index d58d8b9b0029e8f848de96c19c107af3f92a06b6..615020c14b63afa8cead11ebb0085c518e5748cd 100644 (file)
@@ -1,13 +1,12 @@
 /* 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 "10:left shift of negative value|not an integer constant" } */
-  /* { dg-error "left operand of shift expression" "shift" { target c++ } .-1 } */
+  C = -1 << 1, /* { dg-warning "10:left shift of negative value|not an integer constant" "" { target { c || { c++11 && c++17_down } } } } */
+  /* { dg-error "left operand of shift expression" "shift" { target { c++11 && c++17_down } } .-1 } */
   D = 0 >> 1,
   E = 1 >> 1,
   F = -1 >> 1
@@ -23,10 +22,10 @@ left (int x)
   int r = 0;
   r += z << x;
   r += o << x;
-  r += m << x; /* { dg-warning "10:left shift of negative value" } */
+  r += m << x; /* { dg-warning "10:left shift of negative value" "" { target { c || { c++11 && c++17_down } } } } */
   r += 0 << x;
   r += 1 << x;
-  r += -1 << x; /* { dg-warning "11:left shift of negative value" } */
+  r += -1 << x; /* { dg-warning "11:left shift of negative value" "" { target { c || { c++11 && c++17_down } } } } */
   r += -1U << x;
   return r;
 }
diff --git a/gcc/testsuite/c-c++-common/Wshift-negative-value-10.c b/gcc/testsuite/c-c++-common/Wshift-negative-value-10.c
new file mode 100644 (file)
index 0000000..eee414d
--- /dev/null
@@ -0,0 +1,7 @@
+/* PR c/65179 */
+/* { dg-do compile } */
+/* { dg-options "-O -Wshift-negative-value -fwrapv" } */
+/* { dg-additional-options "-std=c++03" { target c++ } } */
+/* { dg-additional-options "-std=c90" { target c } } */
+
+#include "Wshift-negative-value-1.c"
index 9f435e8958d0a5a1d2c9dd946fe3b47d2f3418f8..65e3f30c1372ebe698da98ed5d5fe7dfd7cb8919 100644 (file)
@@ -1,14 +1,13 @@
 /* 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 "10:left shift of negative value" } */
-  /* { dg-error "not an integer constant" "no constant" { target c++ } .-1 } */
-  /* { dg-error "left operand of shift expression" "shift" { target c++ } .-2 } */
+  /* { dg-error "not an integer constant" "no constant" { target { c++11 && c++17_down } } .-1 } */
+  /* { dg-error "left operand of shift expression" "shift" { target { c++11 && c++17_down } } .-2 } */
   D = 0 >> 1,
   E = 1 >> 1,
   F = -1 >> 1
index 503ca61eb6139eb6160f084987c7903496c78c4c..402db9db9c91a6e0ffbe81582db510332400617d 100644 (file)
@@ -1,14 +1,13 @@
 /* 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,
-  /* { dg-error "not an integer constant" "no constant" { target c++ } .-1 } */
-  /* { dg-error "left operand of shift expression" "shift" { target c++ } .-2 } */
+  /* { dg-error "not an integer constant" "no constant" { target { c++11 && c++17_down } } .-1 } */
+  /* { dg-error "left operand of shift expression" "shift" { target { c++11 && c++17_down } } .-2 } */
   D = 0 >> 1,
   E = 1 >> 1,
   F = -1 >> 1
index fa7cb4e7f513af595e60ea67aba343f95644bb60..a47213d81099f0931c5611549f071439906eb48a 100644 (file)
@@ -1,14 +1,13 @@
 /* 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,
-  /* { dg-error "not an integer constant" "no constant" { target c++ } .-1 } */
-  /* { dg-error "left operand of shift expression" "shift" { target c++ } .-2 } */
+  /* { dg-error "not an integer constant" "no constant" { target { c++11 && c++17_down } } .-1 } */
+  /* { dg-error "left operand of shift expression" "shift" { target { c++11 && c++17_down } } .-2 } */
   D = 0 >> 1,
   E = 1 >> 1,
   F = -1 >> 1
diff --git a/gcc/testsuite/c-c++-common/Wshift-negative-value-7.c b/gcc/testsuite/c-c++-common/Wshift-negative-value-7.c
new file mode 100644 (file)
index 0000000..f58b0f1
--- /dev/null
@@ -0,0 +1,5 @@
+/* PR c/65179 */
+/* { dg-do compile } */
+/* { dg-options "-O -Wextra -fwrapv" } */
+
+#include "Wshift-negative-value-1.c"
diff --git a/gcc/testsuite/c-c++-common/Wshift-negative-value-8.c b/gcc/testsuite/c-c++-common/Wshift-negative-value-8.c
new file mode 100644 (file)
index 0000000..d1e5fe7
--- /dev/null
@@ -0,0 +1,5 @@
+/* PR c/65179 */
+/* { dg-do compile } */
+/* { dg-options "-O -Wshift-negative-value -fwrapv" } */
+
+#include "Wshift-negative-value-1.c"
diff --git a/gcc/testsuite/c-c++-common/Wshift-negative-value-9.c b/gcc/testsuite/c-c++-common/Wshift-negative-value-9.c
new file mode 100644 (file)
index 0000000..3243010
--- /dev/null
@@ -0,0 +1,5 @@
+/* PR c/65179 */
+/* { dg-do compile } */
+/* { dg-options "-O -fwrapv" } */
+
+#include "Wshift-negative-value-1.c"
index a69f2b83464c4f14802745684b692d3a31b2858e..be5535f7c23a0b9066c288ad7c3618a2ffcb31a2 100644 (file)
@@ -1,7 +1,6 @@
 /* PR c++/55095 */
 /* { dg-do compile { target int32 } } */
 /* { dg-options "-O" } */
-/* { dg-additional-options "-std=c++11" { target c++ } } */
 
 #define INTM1 (sizeof (int) * __CHAR_BIT__ - 1)
 #define INTM2 (sizeof (int) * __CHAR_BIT__ - 2)
 #define LONG_LONG_MIN (-__LONG_LONG_MAX__-1)
 
 int i1 = 1 << INTM1;
-int i2 = 9 << INTM1; /* { dg-warning "requires 36 bits to represent" } */
-int i3 = 10 << INTM2; /* { dg-warning "requires 35 bits to represent" } */
-int i4 = __INT_MAX__ << 2; /* { dg-warning "requires 34 bits to represent" } */
-int i5 = __INT_MAX__ << INTM1; /* { dg-warning "requires 63 bits to represent" } */
+int i2 = 9 << INTM1; /* { dg-warning "requires 36 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
+int i3 = 10 << INTM2; /* { dg-warning "requires 35 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
+int i4 = __INT_MAX__ << 2; /* { dg-warning "requires 34 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
+int i5 = __INT_MAX__ << INTM1; /* { dg-warning "requires 63 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
 int i6 = -1 << INTM1;
-int i7 = -9 << INTM1; /* { dg-warning "requires 36 bits to represent" } */
-int i8 = -10 << INTM2; /* { dg-warning "requires 35 bits to represent" } */
-int i9 = -__INT_MAX__ << 2; /* { dg-warning "requires 34 bits to represent" } */
-int i10 = -__INT_MAX__ << INTM1; /* { dg-warning "requires 63 bits to represent" } */
-int i11 = INT_MIN << 1; /* { dg-warning "requires 33 bits to represent" } */
+int i7 = -9 << INTM1; /* { dg-warning "requires 36 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
+int i8 = -10 << INTM2; /* { dg-warning "requires 35 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
+int i9 = -__INT_MAX__ << 2; /* { dg-warning "requires 34 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
+int i10 = -__INT_MAX__ << INTM1; /* { dg-warning "requires 63 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
+int i11 = INT_MIN << 1; /* { dg-warning "requires 33 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
 
 int r1 = 1 >> INTM1;
 int r2 = 9 >> INTM1;
@@ -35,29 +34,29 @@ int r9 = -__INT_MAX__ >> 2;
 int r10 = -__INT_MAX__ >> INTM1;
 
 unsigned u1 = 1 << INTM1;
-unsigned u2 = 9 << INTM1; /* { dg-warning "requires 36 bits to represent" } */
+unsigned u2 = 9 << INTM1; /* { dg-warning "requires 36 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
 unsigned u3 = 2U << INTM1;
 unsigned u4 = 9U << INTM1;
 unsigned u5 = 10U << INTM2;
 
 long long int l1 = 1LL << LLONGM1;
-long long int l2 = 9LL << LLONGM1; /* { dg-warning "requires 68 bits to represent" } */
-long long int l3 = 10LL << LLONGM2; /* { dg-warning "requires 67 bits to represent" } */
-long long int l4 = __LONG_LONG_MAX__ << 2; /* { dg-warning "requires 66 bits to represent" } */
-long long int l5 = __LONG_LONG_MAX__ << LLONGM1; /* { dg-warning "requires 127 bits to represent" } */
+long long int l2 = 9LL << LLONGM1; /* { dg-warning "requires 68 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
+long long int l3 = 10LL << LLONGM2; /* { dg-warning "requires 67 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
+long long int l4 = __LONG_LONG_MAX__ << 2; /* { dg-warning "requires 66 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
+long long int l5 = __LONG_LONG_MAX__ << LLONGM1; /* { dg-warning "requires 127 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
 long long int l6 = -1LL << LLONGM1;
-long long int l7 = -9LL << LLONGM1; /* { dg-warning "requires 68 bits to represent" } */
-long long int l8 = -10LL << LLONGM2; /* { dg-warning "requires 67 bits to represent" } */
-long long int l9 = -__LONG_LONG_MAX__ << 2; /* { dg-warning "requires 66 bits to represent" } */
-long long int l10 = -__LONG_LONG_MAX__ << LLONGM1; /* { dg-warning "requires 127 bits to represent" } */
-long long int l11 = LONG_LONG_MIN << 1; /* { dg-warning "requires 65 bits to represent" } */
+long long int l7 = -9LL << LLONGM1; /* { dg-warning "requires 68 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
+long long int l8 = -10LL << LLONGM2; /* { dg-warning "requires 67 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
+long long int l9 = -__LONG_LONG_MAX__ << 2; /* { dg-warning "requires 66 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
+long long int l10 = -__LONG_LONG_MAX__ << LLONGM1; /* { dg-warning "requires 127 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
+long long int l11 = LONG_LONG_MIN << 1; /* { dg-warning "requires 65 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
 
 void
 fn (void)
 {
   const int a = 10;
   const __SIZE_TYPE__ b = INTM1;
-  int k1 = a << b; /* { dg-warning "requires 36 bits to represent" } */
-  int k2 = 10 << b; /* { dg-warning "requires 36 bits to represent" } */
-  int k3 = a << INTM1; /* { dg-warning "requires 36 bits to represent" } */
+  int k1 = a << b; /* { dg-warning "requires 36 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
+  int k2 = 10 << b; /* { dg-warning "requires 36 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
+  int k3 = a << INTM1; /* { dg-warning "requires 36 bits to represent" "" { target { c || { c++11 && c++17_down } } } } */
 }
diff --git a/gcc/testsuite/c-c++-common/Wshift-overflow-10.c b/gcc/testsuite/c-c++-common/Wshift-overflow-10.c
new file mode 100644 (file)
index 0000000..3efd391
--- /dev/null
@@ -0,0 +1,5 @@
+/* PR c++/55095 */
+/* { dg-do compile { target int32 } } */
+/* { dg-options "-O -Wshift-overflow=2 -fwrapv" } */
+
+#include "Wshift-overflow-5.c"
diff --git a/gcc/testsuite/c-c++-common/Wshift-overflow-11.c b/gcc/testsuite/c-c++-common/Wshift-overflow-11.c
new file mode 100644 (file)
index 0000000..9063d80
--- /dev/null
@@ -0,0 +1,5 @@
+/* PR c++/55095 */
+/* { dg-do compile { target int32 } } */
+/* { dg-options "-Wshift-overflow=1 -fwrapv" } */
+
+#include "Wshift-overflow-6.c"
diff --git a/gcc/testsuite/c-c++-common/Wshift-overflow-12.c b/gcc/testsuite/c-c++-common/Wshift-overflow-12.c
new file mode 100644 (file)
index 0000000..5c1c42e
--- /dev/null
@@ -0,0 +1,5 @@
+/* PR c++/55095 */
+/* { dg-do compile { target int32 } } */
+/* { dg-options "-Wshift-overflow=2 -fwrapv" } */
+
+#include "Wshift-overflow-7.c"
index 30fd2552df33e72d6954eee9c98ae1b72c2006dc..3fc05dc4f805c581c3d439e8313c3dad2369488d 100644 (file)
@@ -1,7 +1,6 @@
 /* PR c++/55095 */
 /* { dg-do compile { target int32 } } */
 /* { dg-options "-O -Wno-shift-overflow" } */
-/* { dg-additional-options "-std=c++11" { target c++ } } */
 
 #define INTM1 (sizeof (int) * __CHAR_BIT__ - 1)
 #define INTM2 (sizeof (int) * __CHAR_BIT__ - 2)
index c9f464355dc0cd7401d5dd41a3f72668718798d3..36d617ee254f1d52cffda4248963b9174e1ae89c 100644 (file)
@@ -1,11 +1,10 @@
 /* PR c++/55095 */
 /* { dg-do compile { target int32 } } */
 /* { dg-options "-O -Wshift-overflow=2" } */
-/* { dg-additional-options "-std=c++11" { target c++ } } */
 
 #define INTM1 (sizeof (int) * __CHAR_BIT__ - 1)
 #define LLONGM1 (sizeof (long long) * __CHAR_BIT__ - 1)
 
-int i1 = 1 << INTM1; /* { dg-warning "requires 33 bits to represent" } */
-unsigned u1 = 1 << INTM1; /* { dg-warning "requires 33 bits to represent" } */
-long long int l1 = 1LL << LLONGM1; /* { dg-warning "requires 65 bits to represent" } */
+int i1 = 1 << INTM1; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+unsigned u1 = 1 << INTM1; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+long long int l1 = 1LL << LLONGM1; /* { dg-warning "requires 65 bits to represent" "" { target { c || c++11_down } } } */
index 64797f44a13fd6ce35d6af279269e074b88e85e4..c514118573745b816510030e6362396b7de13fef 100644 (file)
@@ -1,7 +1,6 @@
 /* PR c++/55095 */
 /* { dg-do compile { target int32 } } */
 /* { dg-options "-Wshift-overflow=1" } */
-/* { dg-additional-options "-std=c++11" { target c++ } } */
 
 int i00 = 0b1 << 31;
 int i01 = 0b10 << 30;
@@ -34,4 +33,4 @@ int i27 = 0b1000000000000000000000000000 << 4;
 int i28 = 0b10000000000000000000000000000 << 3;
 int i29 = 0b100000000000000000000000000000 << 2;
 int i30 = 0b1000000000000000000000000000000 << 1;
-int i31 = (int) 0b10000000000000000000000000000000u << 1; /* { dg-warning "requires 33 bits to represent" } */
+int i31 = (int) 0b10000000000000000000000000000000u << 1; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++17_down } } } */
index ca99d2e46fe44281fcb337d85a39ca6719145b48..2779a15c630aec8bff23f72c4bc53c07e9f619d9 100644 (file)
@@ -1,37 +1,36 @@
 /* PR c++/55095 */
 /* { dg-do compile { target int32 } } */
 /* { dg-options "-Wshift-overflow=2" } */
-/* { dg-additional-options "-std=c++11" { target c++ } } */
 
-int i00 = 0b1 << 31; /* { dg-warning "requires 33 bits to represent" } */
-int i01 = 0b10 << 30; /* { dg-warning "requires 33 bits to represent" } */
-int i02 = 0b100 << 29; /* { dg-warning "requires 33 bits to represent" } */
-int i03 = 0b1000 << 28; /* { dg-warning "requires 33 bits to represent" } */
-int i04 = 0b10000 << 27; /* { dg-warning "requires 33 bits to represent" } */
-int i05 = 0b100000 << 26; /* { dg-warning "requires 33 bits to represent" } */
-int i06 = 0b1000000 << 25; /* { dg-warning "requires 33 bits to represent" } */
-int i07 = 0b10000000 << 24; /* { dg-warning "requires 33 bits to represent" } */
-int i08 = 0b100000000 << 23; /* { dg-warning "requires 33 bits to represent" } */
-int i09 = 0b1000000000 << 22; /* { dg-warning "requires 33 bits to represent" } */
-int i10 = 0b10000000000 << 21; /* { dg-warning "requires 33 bits to represent" } */
-int i11 = 0b100000000000 << 20; /* { dg-warning "requires 33 bits to represent" } */
-int i12 = 0b1000000000000 << 19; /* { dg-warning "requires 33 bits to represent" } */
-int i13 = 0b10000000000000 << 18; /* { dg-warning "requires 33 bits to represent" } */
-int i14 = 0b100000000000000 << 17; /* { dg-warning "requires 33 bits to represent" } */
-int i15 = 0b1000000000000000 << 16; /* { dg-warning "requires 33 bits to represent" } */
-int i16 = 0b10000000000000000 << 15; /* { dg-warning "requires 33 bits to represent" } */
-int i17 = 0b100000000000000000 << 14; /* { dg-warning "requires 33 bits to represent" } */
-int i18 = 0b1000000000000000000 << 13; /* { dg-warning "requires 33 bits to represent" } */
-int i19 = 0b10000000000000000000 << 12; /* { dg-warning "requires 33 bits to represent" } */
-int i20 = 0b100000000000000000000 << 11; /* { dg-warning "requires 33 bits to represent" } */
-int i21 = 0b1000000000000000000000 << 10; /* { dg-warning "requires 33 bits to represent" } */
-int i22 = 0b10000000000000000000000 << 9; /* { dg-warning "requires 33 bits to represent" } */
-int i23 = 0b100000000000000000000000 << 8; /* { dg-warning "requires 33 bits to represent" } */
-int i24 = 0b1000000000000000000000000 << 7; /* { dg-warning "requires 33 bits to represent" } */
-int i25 = 0b10000000000000000000000000 << 6; /* { dg-warning "requires 33 bits to represent" } */
-int i26 = 0b100000000000000000000000000 << 5; /* { dg-warning "requires 33 bits to represent" } */
-int i27 = 0b1000000000000000000000000000 << 4; /* { dg-warning "requires 33 bits to represent" } */
-int i28 = 0b10000000000000000000000000000 << 3; /* { dg-warning "requires 33 bits to represent" } */
-int i29 = 0b100000000000000000000000000000 << 2; /* { dg-warning "requires 33 bits to represent" } */
-int i30 = 0b1000000000000000000000000000000 << 1; /* { dg-warning "requires 33 bits to represent" } */
-int i31 = (int) 0b10000000000000000000000000000000u << 1; /* { dg-warning "requires 33 bits to represent" } */
+int i00 = 0b1 << 31; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i01 = 0b10 << 30; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i02 = 0b100 << 29; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i03 = 0b1000 << 28; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i04 = 0b10000 << 27; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i05 = 0b100000 << 26; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i06 = 0b1000000 << 25; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i07 = 0b10000000 << 24; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i08 = 0b100000000 << 23; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i09 = 0b1000000000 << 22; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i10 = 0b10000000000 << 21; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i11 = 0b100000000000 << 20; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i12 = 0b1000000000000 << 19; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i13 = 0b10000000000000 << 18; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i14 = 0b100000000000000 << 17; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i15 = 0b1000000000000000 << 16; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i16 = 0b10000000000000000 << 15; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i17 = 0b100000000000000000 << 14; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i18 = 0b1000000000000000000 << 13; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i19 = 0b10000000000000000000 << 12; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i20 = 0b100000000000000000000 << 11; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i21 = 0b1000000000000000000000 << 10; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i22 = 0b10000000000000000000000 << 9; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i23 = 0b100000000000000000000000 << 8; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i24 = 0b1000000000000000000000000 << 7; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i25 = 0b10000000000000000000000000 << 6; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i26 = 0b100000000000000000000000000 << 5; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i27 = 0b1000000000000000000000000000 << 4; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i28 = 0b10000000000000000000000000000 << 3; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i29 = 0b100000000000000000000000000000 << 2; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i30 = 0b1000000000000000000000000000000 << 1; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++11_down } } } */
+int i31 = (int) 0b10000000000000000000000000000000u << 1; /* { dg-warning "requires 33 bits to represent" "" { target { c || c++17_down } } } */
diff --git a/gcc/testsuite/c-c++-common/Wshift-overflow-8.c b/gcc/testsuite/c-c++-common/Wshift-overflow-8.c
new file mode 100644 (file)
index 0000000..1de228a
--- /dev/null
@@ -0,0 +1,5 @@
+/* PR c++/55095 */
+/* { dg-do compile { target int32 } } */
+/* { dg-options "-O -fwrapv" } */
+
+#include "Wshift-overflow-1.c"
diff --git a/gcc/testsuite/c-c++-common/Wshift-overflow-9.c b/gcc/testsuite/c-c++-common/Wshift-overflow-9.c
new file mode 100644 (file)
index 0000000..7d84bad
--- /dev/null
@@ -0,0 +1,7 @@
+/* PR c++/55095 */
+/* { dg-do compile { target int32 } } */
+/* { dg-options "-O -Wshift-overflow -fwrapv" } */
+/* { dg-additional-options "-std=gnu90" { target c } } */
+/* { dg-additional-options "-std=c++03" { target c++ } } */
+
+#include "Wshift-overflow-1.c"