Message ID | 20250307225444.GA42758@coredump.intra.peff.net (mailing list archive) |
---|---|
State | Accepted |
Commit | 38ca78d9da8179a7f5e1b69ec9f05ecd2000295e |
Headers | show |
Series | config.mak.dev: enable -Wunreachable-code | expand |
Jeff King <peff@peff.net> writes: > I was disappointed that the compiler didn't complain, though. Maybe we > should do this: Indeed. It would have helped us if it were already there in place. > -- >8 -- > Subject: [PATCH] config.mak.dev: enable -Wunreachable-code > > Having the compiler point out unreachable code can help avoid bugs, like > the one discussed in: > > https://lore.kernel.org/git/20250307195057.GA3675279@coredump.intra.peff.net/ > > In that case it was found by Coverity, but finding it earlier saves > everybody time and effort. > > We can use -Wunreachable-code to get some help from the compiler here. > Interestingly, this is a noop in gcc. It was a real warning up until gcc > 4.x, when it was removed for being too flaky, but they left the > command-line option to avoid breaking users. See: > > https://stackoverflow.com/questions/17249934/why-does-gcc-not-warn-for-unreachable-code Wow, now they leave their users confused, making them wondering why their command line option does not do anything useful ;-) > However, clang does implement this option, and it finds the case > mentioned above (and no other cases within the code base). And since we > run clang in several of our CI jobs, that's enough to get an early > warning of breakage. Yes, this is great. Thanks.
On Fri, Mar 07, 2025 at 05:54:45PM -0500, Jeff King wrote: > However, clang does implement this option, and it finds the case > mentioned above (and no other cases within the code base). And since we > run clang in several of our CI jobs, that's enough to get an early > warning of breakage. Hmph, this might be more trouble than it is worth. After correcting the problem in the refs code, the osx CI builds (and only those) now fail with: run-command.c:519:3: error: code will never be executed [-Werror,-Wunreachable-code] die_errno("sigfillset"); ^~~~~~~~~ The code in question is just: if (sigfillset(&all)) die_errno("sigfillset"); So I have to imagine that the issue is that sigfillset() on that platform is an inline or macro that will never return an error, and the compiler can see that. But since POSIX says this can fail (though I'd imagine it's unlikely on most platforms), we should check in the general case. So I don't see how to solve it short of: #ifdef SIGFILLSET_CANNOT_FAIL sigfillset(&all); #else if (sigfillset(&all)) die_errno("sigfillset"); #endif which is rather ugly. It's only used in one spot, so the damage doesn't go too far, but I don't love the idea of getting surprised by the compiler over-analyzing system functions (and having to add Makefile knobs to support it). I guess a knob-less version is: errno = 0; sigfillset(&all); /* don't check return value! only errno */ if (errno) die_errno("sigfillset"); which is subtle, to say the least. -Peff
Jeff King <peff@peff.net> writes: > On Fri, Mar 07, 2025 at 05:54:45PM -0500, Jeff King wrote: > >> However, clang does implement this option, and it finds the case >> mentioned above (and no other cases within the code base). And since we >> run clang in several of our CI jobs, that's enough to get an early >> warning of breakage. > > Hmph, this might be more trouble than it is worth. > > After correcting the problem in the refs code, the osx CI builds (and > only those) now fail with: > > run-command.c:519:3: error: code will never be executed [-Werror,-Wunreachable-code] > die_errno("sigfillset"); > ^~~~~~~~~ > ... > I guess a knob-less version is: > > errno = 0; > sigfillset(&all); /* don't check return value! only errno */ > if (errno) > die_errno("sigfillset"); > > which is subtle, to say the least. Bah. This is just as horrible as some other warnings that are not enabled by default. I guess we should just be more vigilant X-<. Thanks.
On Mon, Mar 10, 2025 at 08:40:46AM -0700, Junio C Hamano wrote: > Jeff King <peff@peff.net> writes: > > > On Fri, Mar 07, 2025 at 05:54:45PM -0500, Jeff King wrote: > > > >> However, clang does implement this option, and it finds the case > >> mentioned above (and no other cases within the code base). And since we > >> run clang in several of our CI jobs, that's enough to get an early > >> warning of breakage. > > > > Hmph, this might be more trouble than it is worth. > > > > After correcting the problem in the refs code, the osx CI builds (and > > only those) now fail with: > > > > run-command.c:519:3: error: code will never be executed [-Werror,-Wunreachable-code] > > die_errno("sigfillset"); > > ^~~~~~~~~ > > ... > > I guess a knob-less version is: > > > > errno = 0; > > sigfillset(&all); /* don't check return value! only errno */ > > if (errno) > > die_errno("sigfillset"); > > > > which is subtle, to say the least. > > Bah. This is just as horrible as some other warnings that are not > enabled by default. I guess we should just be more vigilant X-<. Yeah. We could perhaps live with hacking around this one specific spot. But there's an open question of how often these kinds of false positives will come up. Maybe not often, if there is only one instance in the current code base. Or maybe a lot, but we wouldn't know because we haven't had the warning enabled. I guess another option is to enable it in _one_ CI job that uses clang on Linux (maybe linux-sha256?) and see how often it is helpful or harmful. -Peff
Jeff King <peff@peff.net> writes: > Maybe not often, if there is only one instance in the current code base. > Or maybe a lot, but we wouldn't know because we haven't had the warning > enabled. > > I guess another option is to enable it in _one_ CI job that uses clang > on Linux (maybe linux-sha256?) and see how often it is helpful or > harmful. The reason why you said Linux rather than macOS is because the single instance we know about would not have to be worked around if we did it that way? I am OK with that. Thanks.
diff --git a/config.mak.dev b/config.mak.dev index 0fd8cc4d35..95b7bc46ae 100644 --- a/config.mak.dev +++ b/config.mak.dev @@ -39,6 +39,7 @@ DEVELOPER_CFLAGS += -Wunused DEVELOPER_CFLAGS += -Wvla DEVELOPER_CFLAGS += -Wwrite-strings DEVELOPER_CFLAGS += -fno-common +DEVELOPER_CFLAGS += -Wunreachable-code ifneq ($(filter clang4,$(COMPILER_FEATURES)),) DEVELOPER_CFLAGS += -Wtautological-constant-out-of-range-compare