public inbox for gcc-bugs@sourceware.org help / color / mirror / Atom feed
From: "nisse at lysator dot liu.se" <gcc-bugzilla@gcc.gnu.org> To: gcc-bugs@gcc.gnu.org Subject: [Bug c/94773] New: Unhelpful warning "right shift count >= width of type [-Wshift-count-overflow]" on unreachable code. Date: Sun, 26 Apr 2020 14:19:35 +0000 [thread overview] Message-ID: <bug-94773-4@http.gcc.gnu.org/bugzilla/> (raw) https://gcc.gnu.org/bugzilla/show_bug.cgi?id=94773 Bug ID: 94773 Summary: Unhelpful warning "right shift count >= width of type [-Wshift-count-overflow]" on unreachable code. Product: gcc Version: 10.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: nisse at lysator dot liu.se Target Milestone: --- Consider the following program: ---8<------ /* To avoid including limits.h */ #define CHAR_BIT 8 unsigned shift(unsigned x) { if (sizeof(unsigned) * CHAR_BIT > 32) return x >> 32; else return x >> 1; } ---8<------- I compile this on a debian gnu/linux machine, x86_64, where char is 8 bits and int is 32 bits, and hence the if condition is false. I think the function shift above is well defined C, even if it has a peculiar dependency on the architecture's word size. When compiled with -Wall, I get a warning message on the shift which is in an unreachable branch of the code: $ gcc-10 --version gcc-10 (Debian 10-20200418-1) 10.0.1 20200418 (experimental) [master revision 27c171775ab:4c277008be0:c5bac7d127f288fd2f8a1f15c3f30da5903141c6] Copyright (C) 2020 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. $ gcc-10 -O -Wall -c rshift-warning.c rshift-warning.c: In function ‘shift’: rshift-warning.c:8:14: warning: right shift count >= width of type [-Wshift-count-overflow] 8 | return x >> 32; | ^~ I get the same warning (just different formatting) with gcc-8.3.0. I consider the warning unhelpful, since the code is unreachable precisely because the outer if statement determines that the shift isn't valid. I mean, if I did if (CHAR_BIT != 8) return x / (CHAR_BIT - 8); I wouldn't want to get a warning that the division by the constant zero is invalid. I agree the minimal example is a bit silly, so I can't argue strongly that the warning is unhelpful based on just this example. The actual code where I encountered the problem was the umul_ppmm macro in mini-gmp. It's defined at https://gmplib.org/repo/gmp/file/f4c89b9840ba/mini-gmp/mini-gmp.c#l132 and the first few lines look like this: #define gmp_umul_ppmm(w1, w0, u, v) \ do { \ int LOCAL_GMP_LIMB_BITS = GMP_LIMB_BITS; \ if (sizeof(unsigned int) * CHAR_BIT >= 2 * GMP_LIMB_BITS) \ { \ unsigned int __ww = (unsigned int) (u) * (v); \ w0 = (mp_limb_t) __ww; \ w1 = (mp_limb_t) (__ww >> LOCAL_GMP_LIMB_BITS); \ } \ Gcc doesn't warn for this, but that's because there's a workaround, the LOCAL_GMP_LIMB_BITS variable. For some reason that suppresses the warning. But if I try to simplify this by deleting LOCAL_GMP_LIMB_BITS and instead use GMP_LIMB_BITS in the shift expression, I get the same warning as in the minimal example above, for every expansion of the macro. In my environment, sizeof(unsigned int) == 4, CHAR_BIT == 8, GMP_LIMB_BITS == 64, and mp_limb_t is an alias for unsigned long. For context, it's possible to make this code reachable by changing the way mini-gmp is compiled, e.g., making mp_limb_t an alias for unsigned char, and defining GMP_LIMB_BITS == 8. The purpose of the if statement is to use portable C to determine, at compile time, if unsigned int is large enough to be used to temporarily hold a number of bit size 2*GMP_LIMB_BITS, in which case the following code block is correct. BTW, if the example is written using a conditional expression instead of a conditional statement, unsigned shift(unsigned x) { return (sizeof(unsigned) * CHAR_BIT > 32? x >> 32 : x >> 1); } it does *not* trigger a warning (gcc-8.3 and gcc-10 behave the same). But that kind of rewrite is not an option for the code I'm really interested in.
next reply other threads:[~2020-04-26 14:19 UTC|newest] Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-04-26 14:19 nisse at lysator dot liu.se [this message] 2020-04-26 19:43 ` [Bug c/94773] " vincent-gcc at vinc17 dot net 2020-04-26 21:28 ` nisse at lysator dot liu.se
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=bug-94773-4@http.gcc.gnu.org/bugzilla/ \ --to=gcc-bugzilla@gcc.gnu.org \ --cc=gcc-bugs@gcc.gnu.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).