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.
7 //# This makes an effort to find those inappropriate do_div() calls.
9 // Confidence: Moderate
10 // Copyright: (C) 2020 Wen Yang, Alibaba.
12 // Options: --no-includes --include-headers
21 def get_digit_type_and_value(str):
29 elif (str.upper().endswith('ULL')):
31 value = int(str[:-3], 0)
32 elif (str.upper().endswith('LL')):
34 value = int(str[:-2], 0)
35 elif (str.upper().endswith('UL')):
37 value = int(str[:-2], 0)
38 elif (str.upper().endswith('L')):
40 value = int(str[:-1], 0)
41 elif (str.upper().endswith('U')):
43 value = int(str[:-1], 0)
44 except Exception as e:
49 return is_digit, value
51 def filter_out_safe_constants(str):
52 is_digit, value = get_digit_type_and_value(str)
54 if (value >= 0x100000000):
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
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) };
83 @r depends on (org || report)@
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) };
101 @script:python depends on org@
106 coccilib.org.print_todo(p[0], construct_warnings("div64_ul"))
108 @script:python depends on org@
113 coccilib.org.print_todo(p[0], construct_warnings("div64_long"))
115 @script:python depends on org@
120 coccilib.org.print_todo(p[0], construct_warnings("div64_u64"))
122 @script:python depends on org@
127 coccilib.org.print_todo(p[0], construct_warnings("div64_s64"))
129 @script:python depends on report@
134 coccilib.report.print_report(p[0], construct_warnings("div64_ul"))
136 @script:python depends on report@
141 coccilib.report.print_report(p[0], construct_warnings("div64_long"))
143 @script:python depends on report@
148 coccilib.report.print_report(p[0], construct_warnings("div64_s64"))
150 @script:python depends on report@
155 coccilib.report.print_report(p[0], construct_warnings("div64_u64"))