The mechanism to find possible type tokens can sometimes be confused and go into an infinite loop. This happens for example in QEMU for a line that looks like uint## BITS ##_t S = _S, T = _T; \ uint## BITS ##_t as, at, xs, xt, xd; \ Because the token pasting operator does not have a space before _t, it does not match $notPermitted. However, (?x) is turned on in the regular expression for modifiers, and thus ##_t matches the empty string. As a result, annotate_values goes in an infinite loop. The solution is simply to remove token pasting operators from the string before looking for modifiers. In the example above, the string uintBITS_t will be evaluated as a candidate modifier. This works as long as people do not write things like a##s##m (and fails safely with a false negative if they do), and it fits nicely into sub possible. For a similar reason, \# should be rejected always, even if it is not at end of line or followed by whitespace. Reported-by: Aleksandar Markovic <amarkovic@xxxxxxxxxxxx> Fixes: 89a883530fe7 ("checkpatch: ## is not a valid modifier") Cc: Joe Perches <joe@xxxxxxxxxxx> Cc: Andy Whitcroft <apw@xxxxxxxxxxxxx> Signed-off-by: Paolo Bonzini <pbonzini@xxxxxxxxxx> --- scripts/checkpatch.pl | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index a9c05506e325..0cd8307575e6 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -1915,10 +1915,9 @@ sub possible { else| asm|__asm__| do| - \#| - \#\#| )(?:\s|$)| - ^(?:typedef|struct|enum)\b + ^(?:typedef|struct|enum)\b| + ^\# )}x; warn "CHECK<$possible> ($line)\n" if ($dbg_possible > 2); if ($possible !~ $notPermitted) { @@ -1928,7 +1927,7 @@ sub possible { if ($possible =~ /^\s*$/) { } elsif ($possible =~ /\s/) { - $possible =~ s/\s*$Type\s*//g; + $possible =~ s/\s*(?:$Type|\#\#)\s*//g; for my $modifier (split(' ', $possible)) { if ($modifier !~ $notPermitted) { warn "MODIFIER: $modifier ($possible) ($line)\n" if ($dbg_possible); -- 2.17.1