mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] checkpatch: Add checks for do {} while (0) macro misuses
@ 2012-07-19 22:11 Joe Perches
  2012-07-20 14:40 ` Betty Dall
  0 siblings, 1 reply; 3+ messages in thread
From: Joe Perches @ 2012-07-19 22:11 UTC (permalink / raw)
  To: Andrew Morton; +Cc: Andy Whitcroft, linux-kernel

These types of macros should not be used for either a
single statement nor should the macro end with a semi-colon.

Add tests for these conditions.

Signed-off-by: Joe Perches <joe@perches.com>
---
 scripts/checkpatch.pl |   39 +++++++++++++++++++++++++++++++++++++++
 1 files changed, 39 insertions(+), 0 deletions(-)

diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl
index a743622..da8232b 100755
--- a/scripts/checkpatch.pl
+++ b/scripts/checkpatch.pl
@@ -2988,6 +2988,45 @@ sub process {
 			}
 		}
 
+# do {} while (0) macro tests:
+# single-statement macros do not need to be enclosed in do while (0) loop,
+# macro should not end with a semicolon
+		if ($^V && $^V ge 5.10.0 &&
+		    $realfile !~ m@/vmlinux.lds.h$@ &&
+		    $line =~ /^.\s*\#\s*define\s+$Ident(\()?/) {
+			my $ln = $linenr;
+			my $cnt = $realcnt;
+			my ($off, $dstat, $dcond, $rest);
+			my $ctx = '';
+			($dstat, $dcond, $ln, $cnt, $off) =
+				ctx_statement_block($linenr, $realcnt, 0);
+			$ctx = $dstat;
+
+			$dstat =~ s/\\\n.//g;
+
+			if ($dstat =~ /^\+\s*#\s*define\s+$Ident\s*${balanced_parens}\s*do\s*{(.*)\s*}\s*while\s*\(\s*0\s*\)\s*([;\s]*)\s*$/) {
+				my $stmts = $2;
+				my $semis = $3;
+
+				$ctx =~ s/\n*$//;
+				my $cnt = statement_rawlines($ctx);
+				my $herectx = $here . "\n";
+
+				for (my $n = 0; $n < $cnt; $n++) {
+					$herectx .= raw_line($linenr, $n) . "\n";
+				}
+
+				if (($stmts =~ tr/;/;/) == 1) {
+					WARN("SINGLE_STATEMENT_DO_WHILE_MACRO",
+					     "Single statement macros should not use a do {} while (0) loop\n" . "$herectx");
+				}
+				if (defined $semis && $semis ne "") {
+					WARN("DO_WHILE_MACRO_WITH_TRAILING_SEMICOLON",
+					     "do {} while (0) macros should not be semicolon terminated\n" . "$herectx");
+				}
+			}
+		}
+
 # make sure symbols are always wrapped with VMLINUX_SYMBOL() ...
 # all assignments may have only one of the following with an assignment:
 #	.



^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] checkpatch: Add checks for do {} while (0) macro misuses
  2012-07-19 22:11 [PATCH] checkpatch: Add checks for do {} while (0) macro misuses Joe Perches
@ 2012-07-20 14:40 ` Betty Dall
  2012-07-20 15:49   ` Joe Perches
  0 siblings, 1 reply; 3+ messages in thread
From: Betty Dall @ 2012-07-20 14:40 UTC (permalink / raw)
  To: linux-kernel

Hi Joe,

Joe Perches <joe <at> perches.com> writes:

> 
> These types of macros should not be used for either a
> single statement nor should the macro end with a semi-colon.
> 
> Add tests for these conditions.
> 
> Signed-off-by: Joe Perches <joe <at> perches.com>
> ---
>  scripts/checkpatch.pl |   39 +++++++++++++++++++++++++++++++++++++++
>  1 files changed, 39 insertions(+), 0 deletions(-)


I reviewed this and tested it out on the qib.h file we were looking at yesterday 
and it worked well. I was worried about a nested do {} while(0), because it will 
match with the first while. Here is a test case:
#define qib_devinfo(pcidev, fmt, ...) \
        do { \
                do { \
                        dev_info(&(pcidev)->dev, fmt, ##__VA_ARGS__); \
                } while (0); \
        } while (0)

Checkpatch.pl didn't complain about that one. Granted, it is a contrived test 
case. Your change will catch the real problems.

-Betty




^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH] checkpatch: Add checks for do {} while (0) macro misuses
  2012-07-20 14:40 ` Betty Dall
@ 2012-07-20 15:49   ` Joe Perches
  0 siblings, 0 replies; 3+ messages in thread
From: Joe Perches @ 2012-07-20 15:49 UTC (permalink / raw)
  To: Betty Dall; +Cc: linux-kernel, Andrew Morton, Andy Whitcroft

On Fri, 2012-07-20 at 14:40 +0000, Betty Dall wrote:

> I reviewed this and tested it out on the qib.h file we were looking at yesterday 
> and it worked well. I was worried about a nested do {} while(0), because it will 
> match with the first while. Here is a test case:
> #define qib_devinfo(pcidev, fmt, ...) \
>         do { \
>                 do { \
>                         dev_info(&(pcidev)->dev, fmt, ##__VA_ARGS__); \
>                 } while (0); \
>         } while (0)
> 
> Checkpatch.pl didn't complain about that one. Granted, it is a contrived test 
> case. Your change will catch the real problems.

Hi Betty.

Wow, you're thorough.  Thanks for testing.

I don't mind that it doesn't work in all cases.
I suppose this would fail for loops too.

checkpatch is a pretty limited tool as it depends on
the code being compilable and doesn't really understand
c syntax.  It is just a convenience tool and lots of
its logic is incomplete and some of its output can be
happily ignored.

cheers, Joe


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-07-20 15:49 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-19 22:11 [PATCH] checkpatch: Add checks for do {} while (0) macro misuses Joe Perches
2012-07-20 14:40 ` Betty Dall
2012-07-20 15:49   ` Joe Perches

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®