|
|
Subscribe / Log in / New account

An end to implicit fall-throughs in the kernel

By Jonathan Corbet
August 1, 2019
The C switch statement has, since the beginning of the language, required the use of explicit break statements to prevent execution from falling through from one case to the next. This behavior can be a useful feature, allowing for more compact code, but it can also lead to bugs. The effort to rid the kernel of implicit fall-through coding patterns came to a conclusion with the 5.3-rc2 release, where the last cases were fixed. There is a good chance that these fixes will have to be redone in the future, though.

The problem with C's fall-through behavior is that it is implicit, with no indication of whether the behavior is intended or not. Developers learn (the hard way, sometimes) to end each case with a break statement as a matter of habit, but it's still an easy thing to forget, and the resulting code is seen by the compiler as being entirely valid. A forgotten break almost certainly introduces a bug, even if it might not manifest itself for years. Many developers have had reason to wish that the C language required an explicit indication by the programmer that fall-through behavior is desired.

Making fall-through behavior explicit

The GCC compiler has, for some time, offered a warning option (-Wimplicit-fallthrough) intended to catch missing break statements. It will trigger for any case that falls through into a succeeding case unless an explicit marker has been placed to indicate that the behavior is correct. It turns out that that there are many ways of placing this marker, depending on the value provided with -Wimplicit-fallthrough; the full set can be found in the GCC documentation. At its most lax, the presence of any comment at all prior to a case statement will allow warning-free fall-through into that case. Using -Wimplicit-fallthrough=3 causes the compiler to look for comments matching a fairly large set of regular expressions.

In the kernel, one is most likely to find comments that look like:

StyleCount
/* fallthrough */350
/* fall through */3,091
/* falls through */8
/* fall-through */167

Note that case was ignored in generating the above numbers, and that there are probably other variants in the code as well. All of those comment styles will be recognized by GCC with -Wimplicit-fallthrough=3 and will thus cause warnings to be suppressed.

As can be seen, there are a lot of these comments in the kernel source now, some of which date back to before the beginning of the Git era. Their number has increased in recent times, though, due mostly to a focused effort by Gustavo A. R. Silva, who has been working to eliminate every implicit fall-through warning in the kernel. The point of this effort, beyond fixing any bugs caused by missing break statements, is to make it possible to enable -Wimplicit-fallthrough=3 in the kernel build by default. As long as that option generates a pile of warnings, developers will ignore them and nobody will notice when new ones are added. Once the kernel is warning-free, though, it should be possible to keep it that way.

This work, which was supported by the Linux Foundation, has resulted in over 400 patches since 2017. As Silva has worked through the kernel source eliminating fall-through warnings, he has encountered (and fixed) a number of bugs. A quick search turns up the following commits, for example:

d64062b57eebdrm/amdgpu/gfx10: Fix missing break in switch statement
737298d18836drm/amdkfd: Fix missing break in switch statement
60747828eac2net: socket: Fix missing break in switch statement
84242b82d81crtlwifi: rtl8723ae: Fix missing break in switch statement
7850b51b6c21scsi: mpt3sas: Add missing breaks in switch statements
5e420fe63581scsi: aacraid: Fix missing break in switch statement
09186e503486security: mark expected switch fall-throughs and add a missing break
b5be853181a8crypto: ccree - fix missing break in switch statement
7264235ee74fIB/hfi1: Add missing break in switch statement
cc5034a5d293drm/radeon/evergreen_cs: fix missing break in switch statement
479826cc8611staging: comedi: ni_660x: fix missing break in switch statement
5340f23df8fegpio: sprd: Add missing break in switch statement
df997abeebadiscsi_ibft: Fix missing break in switch statement
2f10d8237396drm/amd/powerplay: Fix missing break in switch
307b00c5e695rtl8xxxu: Fix missing break in switch
5d25ff7a5448scsi: ips: fix missing break in switch
a7ed5b3e7dcastaging: comedi: tio: fix multiple missing break in switch bugs
c24bfa8f21b5spi: slave: Fix missing break in switch
ad0eaee6195dASoC: wm8994: Fix missing break in switch
9ba8376ce1e2ptp: fix missing break in switch
4e57562b4846iio: imu: inv_mpu6050: fix missing break in switch

The above list is clearly incomplete, though, since a number of the other fixes do not explicitly mention missing break statements in the subject line; see commit ed4ed4043a12, for example.

On July 27, a milestone of sorts was hit with this pull into the mainline from Silva's repository: the final implicit fall-through warning has been fixed, and -Wimplicit-fallthrough=3 is now the default for kernel builds. In other words, the kernel's coding style has just been tweaked to disallow the use of implicit fall-through in switch statements. It must be a satisfying conclusion to a long project.

Moving beyond comments

Naturally, though, some developers are not entirely happy with this change. Nobody who actually works in the kernel community seems to disagree with the idea of eliminating implicit fall-throughs, but the mechanism used to do so does not sit well with everybody; as Peter Zijlstra put it back in June: "I still consider it an abomination that the C parser looks at comments". Zijlstra, like others, would prefer that there were another way.

As it happens, there is another way. GCC starting with version 7 allows the use of a special attribute on a statement instead:

    __attribute__((fallthrough))

The use of this attribute can perhaps made more visually pleasing with a definition like:

    #define __fallthrough __attribute__((fallthrough))

The __fallthrough symbol could then be used instead of the magic comments to eliminate implicit fall-through warnings. A patch set implementing this option was posted by Miguel Ojeda in October 2018; it generated a fair amount of interest but was not adopted for a couple of reasons: it doesn't work with older versions of GCC, and the LLVM Clang compiler does not implement that attribute at all. Since Clang does successfully build the kernel in some settings (and is evidently used for the Android build), breaking it is not an appealing option.

The good news is that the Clang developers appear to be working on implementing this attribute. They also, it seems, have an implementation aimed at the proposed next standard for the C language, currently called C2X. The bad news is that the syntax there is different:

    [[fallthrough]]

If this version becomes an actual part of the C standard, it would probably be the preferable one to use going forward. But that may not be fully resolved for some time. In any case, the actual mechanism used to mark explicit fall-through behavior can be hidden behind a #define as shown above.

The one thing that can't be done is:

    #define __fallthrough /* fall through */

since the preprocessor will simply delete the comment rather than substituting it into the source. So the comments have to remain for now. But one can imagine that, at some point in the future when a better alternative is available, those thousands of comments are likely to be replaced with something like __fallthrough in a set of massive, tree-wide patches.

Meanwhile, though, the kernel has finally reached a point where there are no switch statements with implicit fall-through behavior, and the build process has been amended to prevent such behavior from being added in the future. One source of kernel bugs has been closed, a switch that can only be seen as a best-case scenario.

Index entries for this article
KernelCoding style
KernelSecurity/Kernel hardening
SecurityLinux kernel/Hardening


to post comments

> Miguel Ojeda

Posted Aug 2, 2019 2:16 UTC (Fri) by scientes (guest, #83068) [Link] (5 responses)

Numerous people (including me) posted patches avoiding these magic comments. I am the maintainer of distcc, and use of magic comments makes distcc (which compiles the prepossessed files that lack comments) very noisy.

distcc

Posted Aug 2, 2019 10:30 UTC (Fri) by jani (subscriber, #74547) [Link] (3 responses)

> use of magic comments makes distcc (which compiles the prepossessed files that lack comments) very noisy.

Care to elaborate?

distcc

Posted Aug 2, 2019 10:38 UTC (Fri) by mageta (subscriber, #89696) [Link] (2 responses)

I imagine it stems from the fact that distcc sends already pre-processed files to the "compute"-nodes (it does this so the compute-nodes don't need any of the include files and such, so they just need to do the compile-step, which should be free of any "side-effects"). As such they have all comments stripped from them, but the compiler flags are still passed to the compiler running on the compute-node, and because they don't see the comments, they will complain about the missing comments.

Similar things can happen with other certain diagnostics that rely on seeing un-expanded macros (e.g.: -Wtautological-compare). They will complain, because Macros are already expanded in the files sent to the compute-node.

distcc

Posted Aug 2, 2019 12:55 UTC (Fri) by mageta (subscriber, #89696) [Link] (1 responses)

Oh, I forgot, one can suppress the major grunt of these warnings by passing additional CFLAGs into the KBuild system.

When building with distcc, I have been passing 'KCFLAGS=-Wno-tautological-compare' for a while now. This suppresses 95% of the complaints, but not every compiler-call honors KCFLAGS.. and I have been too lazy to track down why that is, its probably a bug.

I imagine one can work around the new warnings from the fall-through diagnostics in a similar way! Have not tested it yet though.

distcc

Posted Aug 2, 2019 18:20 UTC (Fri) by scientes (guest, #83068) [Link]

This is great to know. I will consider adding this by default.

> Miguel Ojeda

Posted Aug 2, 2019 13:44 UTC (Fri) by mathstuf (subscriber, #69389) [Link]

Is `-fdirectives-only` not sufficient? That would end up handling `#include`, and `#if`-like directives (`#define` is handled, but left in the output), leaving macro use in the code itself as-is. I guess the comments still end up being stripped though…but this could help the tautological-compare warnings at least.

An end to implicit fall-throughs in the kernel

Posted Aug 2, 2019 6:01 UTC (Fri) by neilbrown (subscriber, #359) [Link]

> and that there are probably other variants in the code as well.

Indeed ... including 3 "fall though" ( one "fallthough" was recently removed) 14 "Intentional fallthrough" and 10 "lint -fallthrough".

And in case the compiler is a bit deaf,
/* !!!!!!!!! Fall Through !!!!!!!!!!!!! */

Archeology is fun!

An end to implicit fall-throughs in the kernel

Posted Aug 2, 2019 9:36 UTC (Fri) by domo (guest, #14031) [Link]

Thosr /*fallthru*/ comments nevet worked for me, probably since c preprocesdor filtered those out before compiler could see those...

... So i've been wondering how it is possible it is documented and so on...

i've used #if GNUC >= 7 for __attribute__ define and empty define #else.

the hardest thing there has been the #define name.

An end to implicit fall-throughs in the kernel

Posted Aug 2, 2019 10:11 UTC (Fri) by dgm (subscriber, #49227) [Link] (3 responses)

In my experience,

/* fall through */

is OK, but

/* no break */

is superior (from the perspective of a non-native English speaker).

An end to implicit fall-throughs in the kernel

Posted Aug 2, 2019 13:04 UTC (Fri) by Freeaqingme (subscriber, #103259) [Link]

Nonnative speaker reporting in as well. I think programming syntax doesn't have to be 1:1 good English. The brain uses separate 'linguistic registers' for programming languages. So even though a programming language uses primarily English terms, the brain will typically regard them as their own language (or dialect, so you wish) when looking at some code.

So for all intents and purposes they could call it 'foobar', and you'd simply learn what 'foobar' means in this context. Furthermore, I think it's a good practice to actually describe the behavior by what it does, not by what it doesn't do.

As a fun anecdote, the PHP language for a very long time had a T_PAAMAYIM_NEKUDOTAYIM token ('::'). Even though PHP uses primarily English terms, it was written by two Israeli men, who felt it was nice to put something of their own culture/heritage in the language. Undoubtedly it's a bit weird for an English programmer to get an error message 'unexpected T_PAAMAYIM_NEKUDOTAYIM', but after you Google it the first time you simply remember that you probably put some '::' somewhere where the interpreter did not expect it.

An end to implicit fall-throughs in the kernel

Posted Aug 2, 2019 21:35 UTC (Fri) by edeloget (subscriber, #88392) [Link] (1 responses)

/* fall through */ tells what the code is expected to do (i.e. it documents the intention), while /*no break */ is just telling how it's written. The latter could have been added by someone who was surprised that there were no break, and might be a hasitly and lazily written question :)

An end to implicit fall-throughs in the kernel

Posted Aug 5, 2019 10:19 UTC (Mon) by dgm (subscriber, #49227) [Link]

My intention is always to write code that does not break. Sincerely, I hate code that falls throught.

;-P

An end to implicit fall-throughs in the kernel

Posted Aug 2, 2019 12:21 UTC (Fri) by mtthu (subscriber, #123091) [Link] (7 responses)

The somewhat strange looking syntax for the attribute [[fallthrough]] (at least to me it looks a bit strange) seems to be in line with the C++17 standard. Even though I don't really like the double square brackets for the look, the alignment of the C and C++ standards is very desirable to me (and I expect not only to me). I don't think that the C and C++ standards will diverge in this matter. The introduction of the [[fallthrough]] notation in the upcoming C standards seems very likely to me.

BTW: In C++17 two other attributes have been added as well: [[maybe_unused]] and [[nodiscard]]; C++20 adds [[likely]] and [[unlikely]]. Some might be useful in C as well, some not.

An end to implicit fall-throughs in the kernel

Posted Aug 10, 2019 12:04 UTC (Sat) by danieljo (guest, #6161) [Link] (6 responses)

One annoying thing about then [[fallthrouh]] syntax is that it would still need to be hidden behind something like
#if COMPILER_SUPPORT
# define __fallthrough  [[fallthrough]]
#else
# define __fallthrough /*something else*/
#endif
since the following is not valid C and a "raw" [[fallthrough]] is difficult to hide from older compilers.
#if NO_SUPPORT
# define [[fallthrough]] /*something else*/
#endif

An end to implicit fall-throughs in the kernel

Posted Aug 10, 2019 13:31 UTC (Sat) by johill (subscriber, #25196) [Link] (5 responses)

# define __fallthrough /*something else*/

doesn't work one though - the preprocessor will remove the comment, rather than place it

An end to implicit fall-throughs in the kernel

Posted Aug 11, 2019 1:03 UTC (Sun) by nybble41 (subscriber, #55106) [Link] (4 responses)

Since GCC 7 there is a GCC attribute you could use in place of the comment:

#if !defined(__fallthrough) && defined(__has_cpp_attribute)
  #if __has_cpp_attribute(fallthrough)
    #define __fallthrough [[fallthrough]]
  #elif __has_cpp_attribute(gnu::fallthrough)
    #define __fallthrough [[gnu::fallthrough]]
  #endif
#endif

#if !defined(__fallthrough) && defined(__has_attribute)
  #if __has_attribute(__fallthrough__)
    #define __fallthrough __attribute__((__fallthrough__))
  #endif
#endif

#if !defined(__fallthrough) /* well, we tried */
  #define __fallthrough ((void)0)
#endif

An end to implicit fall-throughs in the kernel

Posted Nov 19, 2019 15:26 UTC (Tue) by ballombe (subscriber, #9523) [Link] (3 responses)

Is there a way to say that _all_ the cases in a given switch fall through ? This is very common and
adding 'fall through' at each line instead of once is counterproductive.

An end to implicit fall-throughs in the kernel

Posted Nov 21, 2019 16:04 UTC (Thu) by mathstuf (subscriber, #69389) [Link] (2 responses)

> very common

Do you have an example to show? Other than Duff's device (which I also wouldn't classify as "very common" since it's a stereotypical "what's this weird piece of C doing" snippet), what's the use case?

An end to implicit fall-throughs in the kernel

Posted Nov 24, 2019 22:06 UTC (Sun) by ballombe (subscriber, #9523) [Link] (1 responses)

Handling a data structure with variable length.
switch (strlen(s)-1)
{
case 3: a[3] = cvt3(s[3]);
case 2: a[2] = cvt2(s[2]);
case 1: a[1] = cvt1(s[1]);
case 0: a[0] = cvt0(s[0]);
}
or
switch(a.dim)
{
case 4: checkt(a.t);
case 3: checkz(a.z);
case 2: checky(a.y);
case 1: checkx(a.x);
}

finishing after a loop unrolling

for(i=l;i>=3;i-=4)
{ f(i); f(i-1);f(i-2);f(i-3);}
switch(i)
{
case 3: f(3);
case 2: f(2);
case 1: f(1);
case 0: f(0);
}

conversion
switch(type(z))
{
case FOO: z = FOO_to_BAR(z);
case BAR: z = BAR_to_BAZ(z);
case BAZ: return process_BAZ(z);
}

An end to implicit fall-throughs in the kernel

Posted Nov 25, 2019 16:35 UTC (Mon) by mathstuf (subscriber, #69389) [Link]

> Handling a data structure with variable length.

The first seems like abusing a C string for data storage. A better data structure seems relevant here. It would certainly make the code clearer.

> a.dim

I feel like this would be wrapped up better in a `checkvec` function in the first place. Though this is C; why is one abusing a vec4 to store vec3 or vec2 information (losing cache line benefits given the usual suspects for code using such structures).

> loop unrolling

Something I expect the compiler to be better at today than myself (pending benchmarks showing that the vectorization/unrolling isn't happening).

> conversion

Well, this is what you get with crappy type hierarchies :) . I think the normal way would be something like:

baz* p = NULL;
switch(type(z)) // Assuming `z` is some kind of tagged union structure.
{
case FOO: p = &z->foo.baz; break;
case BAR: p = &z->bar.baz; break;
case BAZ: p = &z->baz;
}
if (p) process_BAZ(p);

These are interesting use cases, but I still wouldn't classify them as "common" or even idiomatic.

An end to implicit fall-throughs in the kernel

Posted Aug 3, 2019 9:06 UTC (Sat) by swilmet (subscriber, #98424) [Link]

An independent thing that makes a missing break more visible in the code, is to add an empty line after each break, to space out cases.

An end to implicit fall-throughs in the kernel

Posted Aug 4, 2019 20:38 UTC (Sun) by rweikusat2 (subscriber, #117920) [Link] (14 responses)

There is no such thing as "implicit fallthrough": A C switch statement causes execution to continue at a certain label depending on the value of the controlling expression. It's basically a specific form of a computed goto and the case-labels are nothing but labels. In absence of explicit control-flow affecting statements, execution continues sequentially after a goto because execution always continues sequentially unless this is changed.

An end to implicit fall-throughs in the kernel

Posted Aug 4, 2019 21:10 UTC (Sun) by mpr22 (subscriber, #60784) [Link] (5 responses)

Is that Sancho Panza standing behind you, by any chance? :)

An end to implicit fall-throughs in the kernel

Posted Aug 5, 2019 14:16 UTC (Mon) by rweikusat2 (subscriber, #117920) [Link] (4 responses)

Try reading the C language definition. The relevant part would seem to be
A switch statement causes control to jump to, into, or past the statement that is the switch body, depending on the value of a controlling expression, and on the presence of a default label and the values of any case labels on or in the switch body. A case or default label is accessible only within the closest enclosing switch statement.
It's just nonsense to refer to the sequential execution of sequence of statemens as "implicit fallthrough" when thinking of C control structures.

An end to implicit fall-throughs in the kernel

Posted Aug 5, 2019 14:53 UTC (Mon) by karkhaz (subscriber, #99844) [Link] (3 responses)

Nobody learns C by reading the standard. People instead use the same mental model for switch statements that they do for if statements, i.e., they are two different ways of writing a conditional expression.

Since you only ever take (at most) one branch of an if statement, it makes sense that programmers expect the same behaviour from the cases of a switch statement. Unlearning this mental model is difficult because people rarely use goto statements and commonly use if statements. So for most people, switch statements are a syntactic sugar for if statements (removing the need to explicitly test the value of the expression for each branch), rather than being sugar for goto statements.

An end to implicit fall-throughs in the kernel

Posted Aug 5, 2019 15:50 UTC (Mon) by rweikusat2 (subscriber, #117920) [Link] (2 responses)

I would suspect assumptions based on how multiway conditionals work in other languages, eg, Pascal or the Bourne shell language, here. Such a construct can be emulated in C by combining switch and break but it doesn't have one. OTOH, a C switch can be used to do things which can't be done with a multiway conditional, eg,
switch ((uintptr_t)p & 3) {
case 3:
    *p++ = c;

case 2:
    *p++ = c;

case 1:
    *p++ = c;
}
to align a pointer while storing some values (I'm aware that this is not standardized C). One could argue that such cases are rare and that a proper multiway conditional had been a better idea.

An end to implicit fall-throughs in the kernel

Posted Aug 5, 2019 18:40 UTC (Mon) by rweikusat2 (subscriber, #117920) [Link]

The pseudo-C-example has the case 3 and case 1 cases inverted :-).

An end to implicit fall-throughs in the kernel

Posted Aug 8, 2019 3:03 UTC (Thu) by Paf (subscriber, #91811) [Link]

In C (not the generated assembly, which isn’t the same thing) a switch statement isn’t *just* a series of jumps. What’s the “break” for if it’s just a set of gotos? It’s a *switch* or *case* statement, and it does indeed have fall through from one condition to the next. It gets to conditions using labels in a manner basically the same as goto, but that’s an implementation detail. Switch/case have a higher level meaning, independent of the generated assembly or the use of labels.

What behavior would constitute “fall through” in your view? Fall through simply means proceeding from one case to the next instead of breaking out. C does so unless told otherwise, so it’s implicit. The fact that the generated assembly is just a set of jumps to labels has no bearing on this higher level language observation, which is comparing C to other languages on the behavior of the switch statement.

Basically you’re saying C doesn’t have fall through at all, because a switch statement is just a set of gotos so we should stop talking about this. That’s certainly *a* perspective. It’s not an interesting or useful one and those of us who want to have a name for this behavior that refers to the higher level language are just going to keep talking about falling through cases.

An end to implicit fall-throughs in the kernel

Posted Aug 5, 2019 16:45 UTC (Mon) by excors (subscriber, #95769) [Link] (3 responses)

If you consider switch to be essentially goto, jumping into the middle of a sequence of statements, then "Go To Statement Considered Harmful" seems relevant. Dijkstra said "we should do (as wise programmers aware of our limitations) our utmost to shorten the conceptual gap between the static program and the dynamic process, to make the correspondence between the program (spread out in text space) and the process (spread out in time) as trivial as possible."

The conceptual gap here is between the switch being a set of mutually exclusive cases (which is how they're typically used, and how they're typically formatted with indentation and braces and blank lines), vs it being a sequence of statements with jumps (which is how it's implemented). After some decades of experience with C, observing all the bugs caused by missing breaks, people have got wise enough to recognise their limitations and are changing the language to reduce that gap.

An end to implicit fall-throughs in the kernel

Posted Aug 5, 2019 21:46 UTC (Mon) by rweikusat2 (subscriber, #117920) [Link] (2 responses)

I suggest you read Dijkstras text. This is more sensible than quoting soundbites wildly out of context.

A switch is a form of computed goto because that's what the language definition says. A "conceptual gap" only manifests itself here if people (wrongly) regard it as something different.

It can't really determine when this feature was implemented but judging from code I've seen, I think lint must have supported flagging absence of break in switch statements since some time in the 1980s and by then, it certainly wasn't based on "decades of experience", probably more on some kind of "This new and different! It must be terribly wrong!!" knee-jerk reaction from people used to something else.

Had Linux not managed fine without this feature for almost three decades, Google employees wouldn't be paid to retrofit it to a large code base.

An end to implicit fall-throughs in the kernel

Posted Aug 5, 2019 22:04 UTC (Mon) by mjg59 (subscriber, #23239) [Link] (1 responses)

It hadn't managed fine. The analysis caught multiple real bugs. Whatever your conceptual objections to this work, it makes a certain category of failure much less likely.

An end to implicit fall-throughs in the kernel

Posted Aug 6, 2019 16:55 UTC (Tue) by rweikusat2 (subscriber, #117920) [Link]

For my definition of "managed fine", it had: I've been using Linux for a long time in all kinds of private and professional settings and I was never forced to fix a bug caused by a missing break. The same will be true for a few millions of other people, otherwise, I wouldn't be writing this here using the software I'm using to write this.

Some analysis of the commits also supports this: The person who worked on this produced 415 commits relating to it. 392 were about adding comments to correct switches. 23 about adding missing breaks. This means that 94.45% of the commits didn't fix anything while 5.54% were bugfixes, presumably mostly to more or less dead code handling corner cases which never happen in practice as the missing breaks would have caused runtime failures otherwise. This gets even more interesting when looking at the number of switch-cases in the kernel code: There are 265,383 of them. Which means that 0.15% didn't have a break and in 0.009% of the cases, this turned out to be wrong. Applying the usual statistican's sleight-of-hand, IOW, assuming that relative frequencies in a particilar statistic are the same as probabilities of a certain outcome in a random selection, one can thus confidently state that "empirical evidence suggests that switch cases are used incorrectly 0.009% of the time!"

That's not my idea of "a serious problem" and even if this was different, I wouldn't consider "make switch harder to use" a sensible solution to it. YMMV.

An end to implicit fall-throughs in the kernel

Posted Aug 15, 2019 10:18 UTC (Thu) by ksandstr (guest, #60862) [Link] (3 responses)

Furthermore, often switch-case is used to have multiple values land execution at the same statement. The syntax for this, i.e. consecutive case labels with no statements in between, is indistinguishable from unannounced fall-through.

The underlying problem here is that switch-case is, with seeming regularity, learned as "what C has for select-case in Visual Basic". That, like many common assumptions regarding C-family languages, is very wrong.

Thirdly, the compiler-oriented solution implies that review will actually compile submitted code and has both care and cojones to require warnings fixed. If that's the case, nice; but I'm not even convinced that any of these "fix fallthru warning" patches' cases were hit in a specific test first to determine that fallthru is actually the correct behaviour. Done wrong, that could be worse than changing nothing.

An end to implicit fall-throughs in the kernel

Posted Aug 15, 2019 17:34 UTC (Thu) by mpr22 (subscriber, #60784) [Link] (2 responses)

> consecutive case labels with no statements in between, is indistinguishable from unannounced fall-through.

It seems to me that "this case label has no statements between it and the next case label" is fairly readily distinguishable from "this case label has statements between it and the next case label, but those statements do not include a break; statement".

An end to implicit fall-throughs in the kernel

Posted Aug 15, 2019 20:29 UTC (Thu) by mjg59 (subscriber, #23239) [Link] (1 responses)

And -wimplicit-fallthrough does make that distinction

An end to implicit fall-throughs in the kernel

Posted Aug 16, 2019 15:02 UTC (Fri) by nybble41 (subscriber, #55106) [Link]

The "implicit fall-through for adjacent case labels" situation doesn't really exist, so there's no need for special handling in -Wimplicit-fallthrough. Labels apply to the following statement; when you have a list of labels with no intervening statements, every label in the list is associated with the same statement at the end, not the next label. You can never end up branching into the middle of a group of labels, so there is no fall-through.

Nobody will notice when new warnings are added...

Posted Aug 7, 2019 13:02 UTC (Wed) by geert (subscriber, #98403) [Link]

> As long as that option generates a pile of warnings, developers will ignore them and nobody will notice when new ones are added.

Of course we notice:

> Below is the list of build error/warning regressions/improvements in
> v5.3-rc3[1] compared to v5.2[2].
>
> 133 warning regressions:

https://lore.kernel.org/lkml/20190806071711.12294-1-geert...

An end to implicit fall-throughs in the kernel

Posted Aug 7, 2019 13:05 UTC (Wed) by geert (subscriber, #98403) [Link]

And to make things even more surprising: it turns out the warnings do not go away when using legacy indentation styles.

https://lore.kernel.org/lkml/CAMuHMdWAboq1YxVVJUop0woJTca...

An end to implicit fall-throughs in the kernel

Posted Aug 16, 2019 17:22 UTC (Fri) by mirabilos (subscriber, #84359) [Link]

BSD lint(1) https://www.mirbsd.org/htman/i386/man1/lint.htm wants /* FALLTHROUGH */ (or /* FALLTHRU */ which is deprecated though).

The (GNU) C præprocessor and GCC also have the option -CC, which is “generally used to support lint comments” but has potentially disturbing side effects. It could be used to define a macro expanding to a comment, though.


Copyright © 2019, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds