162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/// do_div() does a 64-by-32 division.
362306a36Sopenharmony_ci/// When the divisor is long, unsigned long, u64, or s64,
462306a36Sopenharmony_ci/// do_div() truncates it to 32 bits, this means it can test
562306a36Sopenharmony_ci/// non-zero and be truncated to 0 for division on 64bit platforms.
662306a36Sopenharmony_ci///
762306a36Sopenharmony_ci//# This makes an effort to find those inappropriate do_div() calls.
862306a36Sopenharmony_ci//
962306a36Sopenharmony_ci// Confidence: Moderate
1062306a36Sopenharmony_ci// Copyright: (C) 2020 Wen Yang, Alibaba.
1162306a36Sopenharmony_ci// Comments:
1262306a36Sopenharmony_ci// Options: --no-includes --include-headers
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_civirtual context
1562306a36Sopenharmony_civirtual org
1662306a36Sopenharmony_civirtual report
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci@initialize:python@
1962306a36Sopenharmony_ci@@
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_cidef get_digit_type_and_value(str):
2262306a36Sopenharmony_ci    is_digit = False
2362306a36Sopenharmony_ci    value = 0
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci    try:
2662306a36Sopenharmony_ci        if (str.isdigit()):
2762306a36Sopenharmony_ci           is_digit = True
2862306a36Sopenharmony_ci           value =  int(str, 0)
2962306a36Sopenharmony_ci        elif (str.upper().endswith('ULL')):
3062306a36Sopenharmony_ci           is_digit = True
3162306a36Sopenharmony_ci           value = int(str[:-3], 0)
3262306a36Sopenharmony_ci        elif (str.upper().endswith('LL')):
3362306a36Sopenharmony_ci           is_digit = True
3462306a36Sopenharmony_ci           value = int(str[:-2], 0)
3562306a36Sopenharmony_ci        elif (str.upper().endswith('UL')):
3662306a36Sopenharmony_ci           is_digit = True
3762306a36Sopenharmony_ci           value = int(str[:-2], 0)
3862306a36Sopenharmony_ci        elif (str.upper().endswith('L')):
3962306a36Sopenharmony_ci           is_digit = True
4062306a36Sopenharmony_ci           value = int(str[:-1], 0)
4162306a36Sopenharmony_ci        elif (str.upper().endswith('U')):
4262306a36Sopenharmony_ci           is_digit = True
4362306a36Sopenharmony_ci           value = int(str[:-1], 0)
4462306a36Sopenharmony_ci    except Exception as e:
4562306a36Sopenharmony_ci          print('Error:',e)
4662306a36Sopenharmony_ci          is_digit = False
4762306a36Sopenharmony_ci          value = 0
4862306a36Sopenharmony_ci    finally:
4962306a36Sopenharmony_ci        return is_digit, value
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_cidef filter_out_safe_constants(str):
5262306a36Sopenharmony_ci    is_digit, value = get_digit_type_and_value(str)
5362306a36Sopenharmony_ci    if (is_digit):
5462306a36Sopenharmony_ci        if (value >= 0x100000000):
5562306a36Sopenharmony_ci            return True
5662306a36Sopenharmony_ci        else:
5762306a36Sopenharmony_ci            return False
5862306a36Sopenharmony_ci    else:
5962306a36Sopenharmony_ci        return True
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_cidef construct_warnings(suggested_fun):
6262306a36Sopenharmony_ci    msg="WARNING: do_div() does a 64-by-32 division, please consider using %s instead."
6362306a36Sopenharmony_ci    return  msg % suggested_fun
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci@depends on context@
6662306a36Sopenharmony_ciexpression f;
6762306a36Sopenharmony_cilong l: script:python() { filter_out_safe_constants(l) };
6862306a36Sopenharmony_ciunsigned long ul : script:python() { filter_out_safe_constants(ul) };
6962306a36Sopenharmony_ciu64 ul64 : script:python() { filter_out_safe_constants(ul64) };
7062306a36Sopenharmony_cis64 sl64 : script:python() { filter_out_safe_constants(sl64) };
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci@@
7362306a36Sopenharmony_ci(
7462306a36Sopenharmony_ci* do_div(f, l);
7562306a36Sopenharmony_ci|
7662306a36Sopenharmony_ci* do_div(f, ul);
7762306a36Sopenharmony_ci|
7862306a36Sopenharmony_ci* do_div(f, ul64);
7962306a36Sopenharmony_ci|
8062306a36Sopenharmony_ci* do_div(f, sl64);
8162306a36Sopenharmony_ci)
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci@r depends on (org || report)@
8462306a36Sopenharmony_ciexpression f;
8562306a36Sopenharmony_ciposition p;
8662306a36Sopenharmony_cilong l: script:python() { filter_out_safe_constants(l) };
8762306a36Sopenharmony_ciunsigned long ul : script:python() { filter_out_safe_constants(ul) };
8862306a36Sopenharmony_ciu64 ul64 : script:python() { filter_out_safe_constants(ul64) };
8962306a36Sopenharmony_cis64 sl64 : script:python() { filter_out_safe_constants(sl64) };
9062306a36Sopenharmony_ci@@
9162306a36Sopenharmony_ci(
9262306a36Sopenharmony_cido_div@p(f, l);
9362306a36Sopenharmony_ci|
9462306a36Sopenharmony_cido_div@p(f, ul);
9562306a36Sopenharmony_ci|
9662306a36Sopenharmony_cido_div@p(f, ul64);
9762306a36Sopenharmony_ci|
9862306a36Sopenharmony_cido_div@p(f, sl64);
9962306a36Sopenharmony_ci)
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci@script:python depends on org@
10262306a36Sopenharmony_cip << r.p;
10362306a36Sopenharmony_ciul << r.ul;
10462306a36Sopenharmony_ci@@
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_cicoccilib.org.print_todo(p[0], construct_warnings("div64_ul"))
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_ci@script:python depends on org@
10962306a36Sopenharmony_cip << r.p;
11062306a36Sopenharmony_cil << r.l;
11162306a36Sopenharmony_ci@@
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_cicoccilib.org.print_todo(p[0], construct_warnings("div64_long"))
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci@script:python depends on org@
11662306a36Sopenharmony_cip << r.p;
11762306a36Sopenharmony_ciul64 << r.ul64;
11862306a36Sopenharmony_ci@@
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_cicoccilib.org.print_todo(p[0], construct_warnings("div64_u64"))
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci@script:python depends on org@
12362306a36Sopenharmony_cip << r.p;
12462306a36Sopenharmony_cisl64 << r.sl64;
12562306a36Sopenharmony_ci@@
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_cicoccilib.org.print_todo(p[0], construct_warnings("div64_s64"))
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci@script:python depends on report@
13062306a36Sopenharmony_cip << r.p;
13162306a36Sopenharmony_ciul << r.ul;
13262306a36Sopenharmony_ci@@
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_cicoccilib.report.print_report(p[0], construct_warnings("div64_ul"))
13562306a36Sopenharmony_ci
13662306a36Sopenharmony_ci@script:python depends on report@
13762306a36Sopenharmony_cip << r.p;
13862306a36Sopenharmony_cil << r.l;
13962306a36Sopenharmony_ci@@
14062306a36Sopenharmony_ci
14162306a36Sopenharmony_cicoccilib.report.print_report(p[0], construct_warnings("div64_long"))
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci@script:python depends on report@
14462306a36Sopenharmony_cip << r.p;
14562306a36Sopenharmony_cisl64 << r.sl64;
14662306a36Sopenharmony_ci@@
14762306a36Sopenharmony_ci
14862306a36Sopenharmony_cicoccilib.report.print_report(p[0], construct_warnings("div64_s64"))
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci@script:python depends on report@
15162306a36Sopenharmony_cip << r.p;
15262306a36Sopenharmony_ciul64 << r.ul64;
15362306a36Sopenharmony_ci@@
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_cicoccilib.report.print_report(p[0], construct_warnings("div64_u64"))
156