Merge tag 'trace-printf-v6.13' of git://git.kernel.org/pub/scm/linux/kernel/git/trace...
[drm/drm-misc.git] / scripts / coccinelle / misc / do_div.cocci
blob79db083c52087032ba2725ddf6adf4ca026606bf
1 // SPDX-License-Identifier: GPL-2.0-only
2 /// do_div() does a 64-by-32 division.
3 /// When the divisor is long, unsigned long, u64, or s64,
4 /// do_div() truncates it to 32 bits, this means it can test
5 /// non-zero and be truncated to 0 for division on 64bit platforms.
6 ///
7 //# This makes an effort to find those inappropriate do_div() calls.
8 //
9 // Confidence: Moderate
10 // Copyright: (C) 2020 Wen Yang, Alibaba.
11 // Comments:
12 // Options: --no-includes --include-headers
14 virtual context
15 virtual org
16 virtual report
18 @initialize:python@
21 def get_digit_type_and_value(str):
22     is_digit = False
23     value = 0
25     try:
26         if (str.isdigit()):
27            is_digit = True
28            value =  int(str, 0)
29         elif (str.upper().endswith('ULL')):
30            is_digit = True
31            value = int(str[:-3], 0)
32         elif (str.upper().endswith('LL')):
33            is_digit = True
34            value = int(str[:-2], 0)
35         elif (str.upper().endswith('UL')):
36            is_digit = True
37            value = int(str[:-2], 0)
38         elif (str.upper().endswith('L')):
39            is_digit = True
40            value = int(str[:-1], 0)
41         elif (str.upper().endswith('U')):
42            is_digit = True
43            value = int(str[:-1], 0)
44     except Exception as e:
45           print('Error:',e)
46           is_digit = False
47           value = 0
48     finally:
49         return is_digit, value
51 def filter_out_safe_constants(str):
52     is_digit, value = get_digit_type_and_value(str)
53     if (is_digit):
54         if (value >= 0x100000000):
55             return True
56         else:
57             return False
58     else:
59         return True
61 def construct_warnings(suggested_fun):
62     msg="WARNING: do_div() does a 64-by-32 division, please consider using %s instead."
63     return  msg % suggested_fun
65 @depends on context@
66 expression f;
67 long l: script:python() { filter_out_safe_constants(l) };
68 unsigned long ul : script:python() { filter_out_safe_constants(ul) };
69 u64 ul64 : script:python() { filter_out_safe_constants(ul64) };
70 s64 sl64 : script:python() { filter_out_safe_constants(sl64) };
74 * do_div(f, l);
76 * do_div(f, ul);
78 * do_div(f, ul64);
80 * do_div(f, sl64);
83 @r depends on (org || report)@
84 expression f;
85 position p;
86 long l: script:python() { filter_out_safe_constants(l) };
87 unsigned long ul : script:python() { filter_out_safe_constants(ul) };
88 u64 ul64 : script:python() { filter_out_safe_constants(ul64) };
89 s64 sl64 : script:python() { filter_out_safe_constants(sl64) };
92 do_div@p(f, l);
94 do_div@p(f, ul);
96 do_div@p(f, ul64);
98 do_div@p(f, sl64);
101 @script:python depends on org@
102 p << r.p;
103 ul << r.ul;
106 coccilib.org.print_todo(p[0], construct_warnings("div64_ul"))
108 @script:python depends on org@
109 p << r.p;
110 l << r.l;
113 coccilib.org.print_todo(p[0], construct_warnings("div64_long"))
115 @script:python depends on org@
116 p << r.p;
117 ul64 << r.ul64;
120 coccilib.org.print_todo(p[0], construct_warnings("div64_u64"))
122 @script:python depends on org@
123 p << r.p;
124 sl64 << r.sl64;
127 coccilib.org.print_todo(p[0], construct_warnings("div64_s64"))
129 @script:python depends on report@
130 p << r.p;
131 ul << r.ul;
134 coccilib.report.print_report(p[0], construct_warnings("div64_ul"))
136 @script:python depends on report@
137 p << r.p;
138 l << r.l;
141 coccilib.report.print_report(p[0], construct_warnings("div64_long"))
143 @script:python depends on report@
144 p << r.p;
145 sl64 << r.sl64;
148 coccilib.report.print_report(p[0], construct_warnings("div64_s64"))
150 @script:python depends on report@
151 p << r.p;
152 ul64 << r.ul64;
155 coccilib.report.print_report(p[0], construct_warnings("div64_u64"))