From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 8AEE03858C78; Tue, 1 Mar 2022 09:07:17 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 8AEE03858C78 From: "jakub at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug c/104711] Unnecessary -Wshift-negative-value warning Date: Tue, 01 Mar 2022 09:07:17 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: c X-Bugzilla-Version: unknown X-Bugzilla-Keywords: documentation X-Bugzilla-Severity: normal X-Bugzilla-Who: jakub at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: cc Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 X-BeenThere: gcc-bugs@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-bugs mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 01 Mar 2022 09:07:17 -0000 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D104711 Jakub Jelinek changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org, | |jason at gcc dot gnu.org, | |jsm28 at gcc dot gnu.org --- Comment #6 from Jakub Jelinek --- >>From what I can see, -fsanitize=3Dundefined -fwrapv already treats shifts t= he C++20 https://wg21.link/p0907 way, where only the last operand is checked = for being out of bounds (negative or greater or equal to bitsize). N2731 still contains the old (C11 etc.) shift wording. Then we have this -Wshift-negative-value warning which doesn't seem to care about details, complains about left shifts of negative constant always, doe= sn't care about -fwrapv and is enabled in -Wextra for C99 and later and C++11 and later. I'd say we should not warn if TYPE_OVERFLOW_WRAPS (type) aka -fwrapv and we shouldn't enable the warning in -Wextra for C++20 or later. Note, what -fsanitize=3Dundefined actually instruments is beyond the out of bounds y is for signed x << y: C99-C2x ((unsigned) x >> (uprecm1 - y)) !=3D 0 then UB C++11-C++17 x < 0 || ((unsigned) x >> (uprecm1 - y)) > 1 then UB So, I think we want something like: --- 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=3D@var{n} --- 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 =3D TYPE_PRECISION (type0); /* Left-hand operand must be signed. */ - if (TYPE_UNSIGNED (type0) || cxx_dialect >=3D cxx20) + if (TYPE_OVERFLOW_WRAPS (type0) || cxx_dialect >=3D cxx20) return false; unsigned int min_prec =3D (wi::min_precision (wi::to_wide (op0), SIGNED) --- 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 >=3D 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 =3D=3D 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 =3D=3D LSHIFT_EXPR && cxx_dialect >=3D cxx11) --- 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 =3D=3D -1) warn_shift_overflow =3D cxx_dialect >=3D 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 =3D=3D -1) warn_shift_negative_value =3D (extra_warnings - && (cxx_dialect >=3D cxx11 || flag_isoc99)= ); + && (cxx_dialect >=3D 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/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 =3D true; if (TREE_CODE (op0) =3D=3D 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/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 =3D true; if (TREE_CODE (const_op0) =3D=3D INTEGER_CST && tree_int_cst_sgn (const_op0) < 0 + && !TYPE_OVERFLOW_WRAPS (type0) && (complain & tf_warning) && c_inhibit_evaluation_warnings =3D=3D 0) warning_at (location, OPT_Wshift_negative_value, plus testsuite adjustments.=