Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /// do_div() does a 64-by-32 division.
0003 /// When the divisor is long, unsigned long, u64, or s64,
0004 /// do_div() truncates it to 32 bits, this means it can test
0005 /// non-zero and be truncated to 0 for division on 64bit platforms.
0006 ///
0007 //# This makes an effort to find those inappropriate do_div() calls.
0008 //
0009 // Confidence: Moderate
0010 // Copyright: (C) 2020 Wen Yang, Alibaba.
0011 // Comments:
0012 // Options: --no-includes --include-headers
0013 
0014 virtual context
0015 virtual org
0016 virtual report
0017 
0018 @initialize:python@
0019 @@
0020 
0021 def get_digit_type_and_value(str):
0022     is_digit = False
0023     value = 0
0024 
0025     try:
0026         if (str.isdigit()):
0027            is_digit = True
0028            value =  int(str, 0)
0029         elif (str.upper().endswith('ULL')):
0030            is_digit = True
0031            value = int(str[:-3], 0)
0032         elif (str.upper().endswith('LL')):
0033            is_digit = True
0034            value = int(str[:-2], 0)
0035         elif (str.upper().endswith('UL')):
0036            is_digit = True
0037            value = int(str[:-2], 0)
0038         elif (str.upper().endswith('L')):
0039            is_digit = True
0040            value = int(str[:-1], 0)
0041         elif (str.upper().endswith('U')):
0042            is_digit = True
0043            value = int(str[:-1], 0)
0044     except Exception as e:
0045           print('Error:',e)
0046           is_digit = False
0047           value = 0
0048     finally:
0049         return is_digit, value
0050 
0051 def filter_out_safe_constants(str):
0052     is_digit, value = get_digit_type_and_value(str)
0053     if (is_digit):
0054         if (value >= 0x100000000):
0055             return True
0056         else:
0057             return False
0058     else:
0059         return True
0060 
0061 def construct_warnings(suggested_fun):
0062     msg="WARNING: do_div() does a 64-by-32 division, please consider using %s instead."
0063     return  msg % suggested_fun
0064 
0065 @depends on context@
0066 expression f;
0067 long l: script:python() { filter_out_safe_constants(l) };
0068 unsigned long ul : script:python() { filter_out_safe_constants(ul) };
0069 u64 ul64 : script:python() { filter_out_safe_constants(ul64) };
0070 s64 sl64 : script:python() { filter_out_safe_constants(sl64) };
0071 
0072 @@
0073 (
0074 * do_div(f, l);
0075 |
0076 * do_div(f, ul);
0077 |
0078 * do_div(f, ul64);
0079 |
0080 * do_div(f, sl64);
0081 )
0082 
0083 @r depends on (org || report)@
0084 expression f;
0085 position p;
0086 long l: script:python() { filter_out_safe_constants(l) };
0087 unsigned long ul : script:python() { filter_out_safe_constants(ul) };
0088 u64 ul64 : script:python() { filter_out_safe_constants(ul64) };
0089 s64 sl64 : script:python() { filter_out_safe_constants(sl64) };
0090 @@
0091 (
0092 do_div@p(f, l);
0093 |
0094 do_div@p(f, ul);
0095 |
0096 do_div@p(f, ul64);
0097 |
0098 do_div@p(f, sl64);
0099 )
0100 
0101 @script:python depends on org@
0102 p << r.p;
0103 ul << r.ul;
0104 @@
0105 
0106 coccilib.org.print_todo(p[0], construct_warnings("div64_ul"))
0107 
0108 @script:python depends on org@
0109 p << r.p;
0110 l << r.l;
0111 @@
0112 
0113 coccilib.org.print_todo(p[0], construct_warnings("div64_long"))
0114 
0115 @script:python depends on org@
0116 p << r.p;
0117 ul64 << r.ul64;
0118 @@
0119 
0120 coccilib.org.print_todo(p[0], construct_warnings("div64_u64"))
0121 
0122 @script:python depends on org@
0123 p << r.p;
0124 sl64 << r.sl64;
0125 @@
0126 
0127 coccilib.org.print_todo(p[0], construct_warnings("div64_s64"))
0128 
0129 @script:python depends on report@
0130 p << r.p;
0131 ul << r.ul;
0132 @@
0133 
0134 coccilib.report.print_report(p[0], construct_warnings("div64_ul"))
0135 
0136 @script:python depends on report@
0137 p << r.p;
0138 l << r.l;
0139 @@
0140 
0141 coccilib.report.print_report(p[0], construct_warnings("div64_long"))
0142 
0143 @script:python depends on report@
0144 p << r.p;
0145 sl64 << r.sl64;
0146 @@
0147 
0148 coccilib.report.print_report(p[0], construct_warnings("div64_s64"))
0149 
0150 @script:python depends on report@
0151 p << r.p;
0152 ul64 << r.ul64;
0153 @@
0154 
0155 coccilib.report.print_report(p[0], construct_warnings("div64_u64"))