Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

checkpatch: qualify do-while-0 advice

Add a paragraph of advice qualifying the general do-while-0 advice, noting
3 possible misguidings. reduce one ERROR to WARN, for the case I actually
encountered.

And add 'static_assert' to named exceptions, along with some additional
comments about named exceptions vs (detection of) declarative construction
primitives (union, struct, [], etc).

Link: https://lkml.kernel.org/r/20250325235156.663269-3-jim.cromie@gmail.com
Signed-off-by: Jim Cromie <jim.cromie@gmail.com>
Cc: Andy Whitcroft <apw@canonical.com>
Cc: Joe Perches <joe@perches.com>
Cc: Dwaipayan Ray <dwaipayanray1@gmail.com>
Cc: Lukas Bulwahn <lukas.bulwahn@gmail.com>
Cc: Louis Chauvet <louis.chauvet@bootlin.com>
Cc: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>

authored by

Jim Cromie and committed by
Andrew Morton
15d4734c df3d5274

+27 -6
+27 -6
scripts/checkpatch.pl
··· 151 151 exit($exitcode); 152 152 } 153 153 154 + my $DO_WHILE_0_ADVICE = q{ 155 + do {} while (0) advice is over-stated in a few situations: 156 + 157 + The more obvious case is macros, like MODULE_PARM_DESC, invoked at 158 + file-scope, where C disallows code (it must be in functions). See 159 + $exceptions if you have one to add by name. 160 + 161 + More troublesome is declarative macros used at top of new scope, 162 + like DECLARE_PER_CPU. These might just compile with a do-while-0 163 + wrapper, but would be incorrect. Most of these are handled by 164 + detecting struct,union,etc declaration primitives in $exceptions. 165 + 166 + Theres also macros called inside an if (block), which "return" an 167 + expression. These cannot do-while, and need a ({}) wrapper. 168 + 169 + Enjoy this qualification while we work to improve our heuristics. 170 + }; 171 + 154 172 sub uniq { 155 173 my %seen; 156 174 return grep { !$seen{$_}++ } @_; ··· 5901 5883 } 5902 5884 } 5903 5885 5904 - # multi-statement macros should be enclosed in a do while loop, grab the 5905 - # first statement and ensure its the whole macro if its not enclosed 5906 - # in a known good container 5886 + # Usually multi-statement macros should be enclosed in a do {} while 5887 + # (0) loop. Grab the first statement and ensure its the whole macro 5888 + # if its not enclosed in a known good container 5907 5889 if ($realfile !~ m@/vmlinux.lds.h$@ && 5908 5890 $line =~ /^.\s*\#\s*define\s*$Ident(\()?/) { 5909 5891 my $ln = $linenr; ··· 5956 5938 5957 5939 my $exceptions = qr{ 5958 5940 $Declare| 5941 + # named exceptions 5959 5942 module_param_named| 5960 5943 MODULE_PARM_DESC| 5961 5944 DECLARE_PER_CPU| 5962 5945 DEFINE_PER_CPU| 5946 + static_assert| 5947 + # declaration primitives 5963 5948 __typeof__\(| 5964 5949 union| 5965 5950 struct| ··· 5997 5976 ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5998 5977 "Macros starting with if should be enclosed by a do - while loop to avoid possible if/else logic defects\n" . "$herectx"); 5999 5978 } elsif ($dstat =~ /;/) { 6000 - ERROR("MULTISTATEMENT_MACRO_USE_DO_WHILE", 6001 - "Macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx"); 5979 + WARN("MULTISTATEMENT_MACRO_USE_DO_WHILE", 5980 + "Non-declarative macros with multiple statements should be enclosed in a do - while loop\n" . "$herectx\nBUT SEE:\n$DO_WHILE_0_ADVICE"); 6002 5981 } else { 6003 5982 ERROR("COMPLEX_MACRO", 6004 - "Macros with complex values should be enclosed in parentheses\n" . "$herectx"); 5983 + "Macros with complex values should be enclosed in parentheses\n" . "$herectx\nBUT SEE:\n$DO_WHILE_0_ADVICE"); 6005 5984 } 6006 5985 6007 5986 }