File: unsigned.txt

package info (click to toggle)
coccinelle 1.0.8.deb-5
  • links: PTS, VCS
  • area: main
  • in suites: bullseye, sid
  • size: 26,148 kB
  • sloc: ml: 136,392; ansic: 23,594; sh: 2,189; makefile: 2,157; perl: 1,576; lisp: 840; python: 823; awk: 70; csh: 12
file content (129 lines) | stat: -rw-r--r-- 4,140 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
From 12o3l@tiscali.nl Fri Apr 18 18:13:39 2008
Date: Fri, 18 Apr 2008 18:15:06 +0200
From: Roel Kluin <12o3l@tiscali.nl>
To: kernel-janitors@vger.kernel.org, kernelnewbies-bounce@nl.linux.org
Subject: script to find incorrect tests on unsigneds

A bash script to find incorrect tests on unsigned values. for instance:

unsigned int i;
...
i = neg_ret_function();
...
if (i < 0) ...

#!/bin/bash
# (c) roel kluin 2008 GPL v2
#
# TODO: make this working also for 
#                              ... $unsigned_var == $signed_var ...
#                              ... $unsigned_var == \(-POSITIVE_DEF\|NEGATIVE_DEF\) ...
#                              ... ( $unsigned_var [+*/%^&~-]?= ... ) < 0 ...

# a number
int="[0-9]"
hex="[a-f0-9]"
hEx="[A-Fa-f0-9]"
HEX="[A-F0-9]"
upp="[A-Z]"
up_="[A-Z_]"
low="[a-z0-9]"
lo_="[a-z0-9_]"
alp="[A-Za-z]"
al_="[A-Za-z_]"
ALN="[A-Z0-9]"
AN_="[A-Z0-9_]"
aln="[A-Za-z0-9]"
an_="[A-Za-z0-9_]"
# to match something like 1ul, floats or hexes as well:
D="$int*\.\?$int\+x\?$hex*[uUlL]\{0,3\}[fF]\?"

# more strict and catches it (costs one backreference for (git-)grep)
d="\($int\+[uUlLfF]\?\|$int\+[uU]\?[lL][lL]\?\|0x$hex\+\|0x$HEX\+\|$i\+[lL][lL][uU]\|$i*\.$i\+[fF]\?\)"

# capital: can be used to catch a definition or config option
K="$UP_\+$AN_*";

# can be used for a variable/function name:
V="$an_\+$an_*"

# works the same as above, but also for members and arrays: one backreference
# is more strict
W="$V\(\[$s$V$s\]\|\[$s$D$s\]\|\.$V\|->$V\)*"
# catches it at once (less strict)
w="\($V\|${V}\[$s$an_*${s}\]\|$V\.\|$V->\)\+"

# separators:
s="[[:space:]]*";
S="[[:space:]]\+"

# useful to delimit a variable name:
Q="[^[:alnum:]_]"

# match the end of the line, including comments: one backreference (but at eol)
cendl="$s\(\/[\*\/].*\)\?$"

# match something that is not comment, string or character: 2 backreferences
ccode="\([^\/\"']*\|\/[^\*\/]\|\/\*\([^\*]*\|\**[^\/\*]\)*\*\+\/\|'[^']*'\|\"[^\"]*\"\)*"

# resp function open and end (only works when indentation is correct.
fo="^[\{]$cendl"
fe="^[\}]$cendl"
se="^[\}];$cendl"

# to match nested parentheses
nps="[^()]*"
nstdps="\(($nps\(($nps\(($nps\(($nps\(($nps)$nps\)*)$nps\)*)$nps\)*)$nps\)*)$nps\)*"


# first determine unsigned typedefs
arr="\(\[[^\]]*\]$s\)*"
attr="__attribute__$s(([^;]*))"
utype="${s}typedef${S}unsigned$S\($V$S\)*"
uns="unsigned$(
git-grep "^$utype\($V$s$arr\|$attr$S$V$s$arr\|$V$s$arr$S$attr\)$s;$cendl" | sed -n "s/^[^.]*\.[hc]:$utype\(\($V\)$s$arr\|$attr$S\($V\)$s$arr\|\($V\)$s$arr$S$attr\)$s;$cendl/\\\\|\3\5\7/p" | sort | uniq | tr -d "\n")"

# define left and right operators
# to decrease the number backrefences, these are assigned in loops
opl=
for op in "[;,|^?:(]" "[\!+*/%&|~^-]=" ">>=" "<<=" "\[" "&&" "$an_$s&"; do 
 opl="$opl$op\|$op$s++\|$op$s--\|"
done
opl="\(${opl%|})"
opr=
for op in "[;,&|^?:)]" "[\!+*/%&|~^<>-]=" ">>=" "<<=" ">[^>]" "<[^<]" "\]"; do 
 opr="$opr$op\|$op$s++\|$op$s--\|"
done
opr="\(${opr%|})"

# string catches invalid comparison
q1="$opl$s\($w$s\(>=${s}0\|<${s}0\|[><\!=]=$s-$s$D\|[<>]$s-$s$D\)\|\(0$s>\|0$s<=\|-$s$D${s}[><\!=]=\|-$s$D${s}[<>]\)$s$w\)$s$opr"

start=0
end=$(echo $uns | tr -cd "|" | wc -c)

# main function
while [ $start -lt $end ]; do
  # we match 30 typedefs at a time
  tuns="$(echo $uns | cut -d "\\" -f$start-$(($start+29)))"

  # catch candidate files 
  for f in $(git-grep -l "^\(${ccode}[,;]$s\)\?\($tuns\)$S" | grep "[^.]*\.[ch]" | xargs grep -l "$q1"); do
    for n in $(sed -n "/^.*$q1/=" $f); do # lines
      for v in $(sed -n "${n}s/^.*$q1.*$/\3\6/p" $f); do
        # n2 = wine there
        head -n$n $f | tac | sed -n "/^[{]/q; /^\(.*$Q\)\?\($tuns\)$S\($V$S\)*$v$Q.*$/=" | while read n2;        
        do
          echo "# --- invalid test on unsigned variable '$v' --- #"
          echo "vi $f +$n2 # unsigned declaration"
          echo "vi $f +$n # invalid test"
        done
      done
    done
  done
  start=$(($start+30))
done | less
--
To unsubscribe from this list: send the line "unsubscribe kernel-janitors" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html