[PATCH] c, c++, c-family: -Wshift-negative-value and -Wshift-overflow* tweaks for -fwrapv and C++20+ [PR104711]

Jason Merrill jason@redhat.com
Tue Mar 8 23:16:02 GMT 2022


On 3/2/22 05:22, Jakub Jelinek wrote:
> Hi!
> 
> 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.
> 
> Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

OK.

> 2022-03-02  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.
> 
> --- gcc/doc/invoke.texi.jj	2022-02-25 10:46:53.085181500 +0100
> +++ gcc/doc/invoke.texi	2022-03-01 09:59:15.040855224 +0100
> @@ -5809,7 +5809,7 @@ name is still supported, but the newer n
>   -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
>   @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}
> --- gcc/c-family/c-opts.cc.jj	2022-01-18 11:58:58.884992028 +0100
> +++ gcc/c-family/c-opts.cc	2022-03-01 09:57:34.880253831 +0100
> @@ -934,10 +934,12 @@ c_common_post_options (const char **pfil
>     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,
> --- gcc/c-family/c-ubsan.cc.jj	2022-02-09 15:15:59.288840032 +0100
> +++ gcc/c-family/c-ubsan.cc	2022-03-01 09:55:51.779693845 +0100
> @@ -173,7 +173,7 @@ ubsan_instrument_shift (location_t loc,
>         || 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,
>   			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)
> --- gcc/c-family/c-warn.cc.jj	2022-01-18 11:58:58.922991486 +0100
> +++ gcc/c-family/c-warn.cc	2022-03-01 10:02:41.634971050 +0100
> @@ -2605,7 +2605,7 @@ maybe_warn_shift_overflow (location_t lo
>     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)
> --- gcc/c/c-fold.cc.jj	2022-02-09 20:45:24.253211303 +0100
> +++ gcc/c/c-fold.cc	2022-03-01 11:39:32.153859825 +0100
> @@ -382,6 +382,7 @@ c_fully_fold_internal (tree expr, bool i
>   	  && 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");
> --- gcc/c/c-typeck.cc.jj	2022-02-11 00:19:22.135067293 +0100
> +++ gcc/c/c-typeck.cc	2022-03-01 10:04:20.925584897 +0100
> @@ -12213,7 +12213,8 @@ build_binary_op (location_t location, en
>   	{
>   	  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.  */
> --- gcc/cp/constexpr.cc.jj	2022-02-18 12:37:51.081601299 +0100
> +++ gcc/cp/constexpr.cc	2022-03-01 11:56:12.874890444 +0100
> @@ -3165,7 +3165,7 @@ cxx_eval_check_shift_p (location_t loc,
>        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)
>       {
> --- gcc/cp/typeck.cc.jj	2022-02-18 12:38:06.065393230 +0100
> +++ gcc/cp/typeck.cc	2022-03-01 10:04:57.726071137 +0100
> @@ -5382,6 +5382,7 @@ cp_build_binary_op (const op_location_t
>   	  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,
> --- gcc/testsuite/c-c++-common/Wshift-negative-value-1.c.jj	2020-01-12 11:54:36.995404628 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-negative-value-1.c	2022-03-01 11:43:47.217299318 +0100
> @@ -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;
>   }
> --- gcc/testsuite/c-c++-common/Wshift-negative-value-2.c.jj	2020-01-12 11:54:36.995404628 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-negative-value-2.c	2022-03-01 11:47:41.695026169 +0100
> @@ -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
> --- gcc/testsuite/c-c++-common/Wshift-negative-value-3.c.jj	2020-01-12 11:54:36.995404628 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-negative-value-3.c	2022-03-01 11:48:01.029756269 +0100
> @@ -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
> --- gcc/testsuite/c-c++-common/Wshift-negative-value-4.c.jj	2020-01-12 11:54:36.995404628 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-negative-value-4.c	2022-03-01 11:48:46.740118184 +0100
> @@ -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
> --- gcc/testsuite/c-c++-common/Wshift-negative-value-7.c.jj	2022-03-01 11:00:56.877179511 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-negative-value-7.c	2022-03-01 11:59:32.535103327 +0100
> @@ -0,0 +1,5 @@
> +/* PR c/65179 */
> +/* { dg-do compile } */
> +/* { dg-options "-O -Wextra -fwrapv" } */
> +
> +#include "Wshift-negative-value-1.c"
> --- gcc/testsuite/c-c++-common/Wshift-negative-value-8.c.jj	2022-03-01 11:01:41.087562363 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-negative-value-8.c	2022-03-01 11:59:43.084956059 +0100
> @@ -0,0 +1,5 @@
> +/* PR c/65179 */
> +/* { dg-do compile } */
> +/* { dg-options "-O -Wshift-negative-value -fwrapv" } */
> +
> +#include "Wshift-negative-value-1.c"
> --- gcc/testsuite/c-c++-common/Wshift-negative-value-9.c.jj	2022-03-01 11:02:38.837756210 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-negative-value-9.c	2022-03-01 11:59:51.733835326 +0100
> @@ -0,0 +1,5 @@
> +/* PR c/65179 */
> +/* { dg-do compile } */
> +/* { dg-options "-O -fwrapv" } */
> +
> +#include "Wshift-negative-value-1.c"
> --- gcc/testsuite/c-c++-common/Wshift-negative-value-10.c.jj	2022-03-01 11:03:28.922057068 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-negative-value-10.c	2022-03-01 11:03:44.101845168 +0100
> @@ -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"
> --- gcc/testsuite/c-c++-common/Wshift-overflow-1.c.jj	2020-01-12 11:54:36.995404628 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-overflow-1.c	2022-03-01 12:01:33.792410660 +0100
> @@ -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)
> @@ -12,16 +11,16 @@
>   #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 } } } } */
>   }
> --- gcc/testsuite/c-c++-common/Wshift-overflow-2.c.jj	2020-01-12 11:54:36.995404628 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-overflow-2.c	2022-03-01 11:20:16.498991992 +0100
> @@ -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)
> --- gcc/testsuite/c-c++-common/Wshift-overflow-5.c.jj	2020-01-12 11:54:36.995404628 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-overflow-5.c	2022-03-01 12:05:27.955141905 +0100
> @@ -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 } } } */
> --- gcc/testsuite/c-c++-common/Wshift-overflow-6.c.jj	2020-01-12 11:54:36.995404628 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-overflow-6.c	2022-03-01 12:06:15.950471922 +0100
> @@ -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
>   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 } } } */
> --- gcc/testsuite/c-c++-common/Wshift-overflow-7.c.jj	2020-01-12 11:54:36.995404628 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-overflow-7.c	2022-03-01 12:08:09.738883507 +0100
> @@ -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 } } } */
> --- gcc/testsuite/c-c++-common/Wshift-overflow-8.c.jj	2022-03-01 11:06:15.451732430 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-overflow-8.c	2022-03-01 11:21:43.500777502 +0100
> @@ -0,0 +1,5 @@
> +/* PR c++/55095 */
> +/* { dg-do compile { target int32 } } */
> +/* { dg-options "-O -fwrapv" } */
> +
> +#include "Wshift-overflow-1.c"
> --- gcc/testsuite/c-c++-common/Wshift-overflow-9.c.jj	2022-03-01 11:07:04.998040795 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-overflow-9.c	2022-03-01 11:07:30.015691566 +0100
> @@ -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"
> --- gcc/testsuite/c-c++-common/Wshift-overflow-10.c.jj	2022-03-01 11:09:17.167195807 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-overflow-10.c	2022-03-01 11:21:54.518623704 +0100
> @@ -0,0 +1,5 @@
> +/* PR c++/55095 */
> +/* { dg-do compile { target int32 } } */
> +/* { dg-options "-O -Wshift-overflow=2 -fwrapv" } */
> +
> +#include "Wshift-overflow-5.c"
> --- gcc/testsuite/c-c++-common/Wshift-overflow-11.c.jj	2022-03-01 11:09:46.991779477 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-overflow-11.c	2022-03-01 11:21:59.235557860 +0100
> @@ -0,0 +1,5 @@
> +/* PR c++/55095 */
> +/* { dg-do compile { target int32 } } */
> +/* { dg-options "-Wshift-overflow=1 -fwrapv" } */
> +
> +#include "Wshift-overflow-6.c"
> --- gcc/testsuite/c-c++-common/Wshift-overflow-12.c.jj	2022-03-01 11:10:19.121330974 +0100
> +++ gcc/testsuite/c-c++-common/Wshift-overflow-12.c	2022-03-01 11:22:04.561483512 +0100
> @@ -0,0 +1,5 @@
> +/* PR c++/55095 */
> +/* { dg-do compile { target int32 } } */
> +/* { dg-options "-Wshift-overflow=2 -fwrapv" } */
> +
> +#include "Wshift-overflow-7.c"
> 
> 	Jakub
> 



More information about the Gcc-patches mailing list