xref: /linux/scripts/coccinelle/misc/do_div.cocci (revision 03ab8e6297acd1bc0eedaa050e2a1635c576fd11)
1*ac5f3136SWen Yang// SPDX-License-Identifier: GPL-2.0-only
2*ac5f3136SWen Yang/// do_div() does a 64-by-32 division.
3*ac5f3136SWen Yang/// When the divisor is long, unsigned long, u64, or s64,
4*ac5f3136SWen Yang/// do_div() truncates it to 32 bits, this means it can test
5*ac5f3136SWen Yang/// non-zero and be truncated to 0 for division on 64bit platforms.
6*ac5f3136SWen Yang///
7*ac5f3136SWen Yang//# This makes an effort to find those inappropriate do_div() calls.
8*ac5f3136SWen Yang//
9*ac5f3136SWen Yang// Confidence: Moderate
10*ac5f3136SWen Yang// Copyright: (C) 2020 Wen Yang, Alibaba.
11*ac5f3136SWen Yang// Comments:
12*ac5f3136SWen Yang// Options: --no-includes --include-headers
13*ac5f3136SWen Yang
14*ac5f3136SWen Yangvirtual context
15*ac5f3136SWen Yangvirtual org
16*ac5f3136SWen Yangvirtual report
17*ac5f3136SWen Yang
18*ac5f3136SWen Yang@initialize:python@
19*ac5f3136SWen Yang@@
20*ac5f3136SWen Yang
21*ac5f3136SWen Yangdef get_digit_type_and_value(str):
22*ac5f3136SWen Yang    is_digit = False
23*ac5f3136SWen Yang    value = 0
24*ac5f3136SWen Yang
25*ac5f3136SWen Yang    try:
26*ac5f3136SWen Yang        if (str.isdigit()):
27*ac5f3136SWen Yang           is_digit = True
28*ac5f3136SWen Yang           value =  int(str, 0)
29*ac5f3136SWen Yang        elif (str.upper().endswith('ULL')):
30*ac5f3136SWen Yang           is_digit = True
31*ac5f3136SWen Yang           value = int(str[:-3], 0)
32*ac5f3136SWen Yang        elif (str.upper().endswith('LL')):
33*ac5f3136SWen Yang           is_digit = True
34*ac5f3136SWen Yang           value = int(str[:-2], 0)
35*ac5f3136SWen Yang        elif (str.upper().endswith('UL')):
36*ac5f3136SWen Yang           is_digit = True
37*ac5f3136SWen Yang           value = int(str[:-2], 0)
38*ac5f3136SWen Yang        elif (str.upper().endswith('L')):
39*ac5f3136SWen Yang           is_digit = True
40*ac5f3136SWen Yang           value = int(str[:-1], 0)
41*ac5f3136SWen Yang        elif (str.upper().endswith('U')):
42*ac5f3136SWen Yang           is_digit = True
43*ac5f3136SWen Yang           value = int(str[:-1], 0)
44*ac5f3136SWen Yang    except Exception as e:
45*ac5f3136SWen Yang          print('Error:',e)
46*ac5f3136SWen Yang          is_digit = False
47*ac5f3136SWen Yang          value = 0
48*ac5f3136SWen Yang    finally:
49*ac5f3136SWen Yang        return is_digit, value
50*ac5f3136SWen Yang
51*ac5f3136SWen Yangdef filter_out_safe_constants(str):
52*ac5f3136SWen Yang    is_digit, value = get_digit_type_and_value(str)
53*ac5f3136SWen Yang    if (is_digit):
54*ac5f3136SWen Yang        if (value >= 0x100000000):
55*ac5f3136SWen Yang            return True
56*ac5f3136SWen Yang        else:
57*ac5f3136SWen Yang            return False
58*ac5f3136SWen Yang    else:
59*ac5f3136SWen Yang        return True
60*ac5f3136SWen Yang
61*ac5f3136SWen Yangdef construct_warnings(suggested_fun):
62*ac5f3136SWen Yang    msg="WARNING: do_div() does a 64-by-32 division, please consider using %s instead."
63*ac5f3136SWen Yang    return  msg % suggested_fun
64*ac5f3136SWen Yang
65*ac5f3136SWen Yang@depends on context@
66*ac5f3136SWen Yangexpression f;
67*ac5f3136SWen Yanglong l: script:python() { filter_out_safe_constants(l) };
68*ac5f3136SWen Yangunsigned long ul : script:python() { filter_out_safe_constants(ul) };
69*ac5f3136SWen Yangu64 ul64 : script:python() { filter_out_safe_constants(ul64) };
70*ac5f3136SWen Yangs64 sl64 : script:python() { filter_out_safe_constants(sl64) };
71*ac5f3136SWen Yang
72*ac5f3136SWen Yang@@
73*ac5f3136SWen Yang(
74*ac5f3136SWen Yang* do_div(f, l);
75*ac5f3136SWen Yang|
76*ac5f3136SWen Yang* do_div(f, ul);
77*ac5f3136SWen Yang|
78*ac5f3136SWen Yang* do_div(f, ul64);
79*ac5f3136SWen Yang|
80*ac5f3136SWen Yang* do_div(f, sl64);
81*ac5f3136SWen Yang)
82*ac5f3136SWen Yang
83*ac5f3136SWen Yang@r depends on (org || report)@
84*ac5f3136SWen Yangexpression f;
85*ac5f3136SWen Yangposition p;
86*ac5f3136SWen Yanglong l: script:python() { filter_out_safe_constants(l) };
87*ac5f3136SWen Yangunsigned long ul : script:python() { filter_out_safe_constants(ul) };
88*ac5f3136SWen Yangu64 ul64 : script:python() { filter_out_safe_constants(ul64) };
89*ac5f3136SWen Yangs64 sl64 : script:python() { filter_out_safe_constants(sl64) };
90*ac5f3136SWen Yang@@
91*ac5f3136SWen Yang(
92*ac5f3136SWen Yangdo_div@p(f, l);
93*ac5f3136SWen Yang|
94*ac5f3136SWen Yangdo_div@p(f, ul);
95*ac5f3136SWen Yang|
96*ac5f3136SWen Yangdo_div@p(f, ul64);
97*ac5f3136SWen Yang|
98*ac5f3136SWen Yangdo_div@p(f, sl64);
99*ac5f3136SWen Yang)
100*ac5f3136SWen Yang
101*ac5f3136SWen Yang@script:python depends on org@
102*ac5f3136SWen Yangp << r.p;
103*ac5f3136SWen Yangul << r.ul;
104*ac5f3136SWen Yang@@
105*ac5f3136SWen Yang
106*ac5f3136SWen Yangcoccilib.org.print_todo(p[0], construct_warnings("div64_ul"))
107*ac5f3136SWen Yang
108*ac5f3136SWen Yang@script:python depends on org@
109*ac5f3136SWen Yangp << r.p;
110*ac5f3136SWen Yangl << r.l;
111*ac5f3136SWen Yang@@
112*ac5f3136SWen Yang
113*ac5f3136SWen Yangcoccilib.org.print_todo(p[0], construct_warnings("div64_long"))
114*ac5f3136SWen Yang
115*ac5f3136SWen Yang@script:python depends on org@
116*ac5f3136SWen Yangp << r.p;
117*ac5f3136SWen Yangul64 << r.ul64;
118*ac5f3136SWen Yang@@
119*ac5f3136SWen Yang
120*ac5f3136SWen Yangcoccilib.org.print_todo(p[0], construct_warnings("div64_u64"))
121*ac5f3136SWen Yang
122*ac5f3136SWen Yang@script:python depends on org@
123*ac5f3136SWen Yangp << r.p;
124*ac5f3136SWen Yangsl64 << r.sl64;
125*ac5f3136SWen Yang@@
126*ac5f3136SWen Yang
127*ac5f3136SWen Yangcoccilib.org.print_todo(p[0], construct_warnings("div64_s64"))
128*ac5f3136SWen Yang
129*ac5f3136SWen Yang@script:python depends on report@
130*ac5f3136SWen Yangp << r.p;
131*ac5f3136SWen Yangul << r.ul;
132*ac5f3136SWen Yang@@
133*ac5f3136SWen Yang
134*ac5f3136SWen Yangcoccilib.report.print_report(p[0], construct_warnings("div64_ul"))
135*ac5f3136SWen Yang
136*ac5f3136SWen Yang@script:python depends on report@
137*ac5f3136SWen Yangp << r.p;
138*ac5f3136SWen Yangl << r.l;
139*ac5f3136SWen Yang@@
140*ac5f3136SWen Yang
141*ac5f3136SWen Yangcoccilib.report.print_report(p[0], construct_warnings("div64_long"))
142*ac5f3136SWen Yang
143*ac5f3136SWen Yang@script:python depends on report@
144*ac5f3136SWen Yangp << r.p;
145*ac5f3136SWen Yangsl64 << r.sl64;
146*ac5f3136SWen Yang@@
147*ac5f3136SWen Yang
148*ac5f3136SWen Yangcoccilib.report.print_report(p[0], construct_warnings("div64_s64"))
149*ac5f3136SWen Yang
150*ac5f3136SWen Yang@script:python depends on report@
151*ac5f3136SWen Yangp << r.p;
152*ac5f3136SWen Yangul64 << r.ul64;
153*ac5f3136SWen Yang@@
154*ac5f3136SWen Yang
155*ac5f3136SWen Yangcoccilib.report.print_report(p[0], construct_warnings("div64_u64"))
156