Andrzej Hajda | 3f984cb | 2016-01-07 10:36:51 +0100 | [diff] [blame] | 1 | /// Unsigned expressions cannot be lesser than zero. Presence of |
| 2 | /// comparisons 'unsigned (<|<=|>|>=) 0' often indicates a bug, |
| 3 | /// usually wrong type of variable. |
| 4 | /// |
| 5 | /// To reduce number of false positives following tests have been added: |
| 6 | /// - parts of range checks are skipped, eg. "if (u < 0 || u > 15) ...", |
| 7 | /// developers prefer to keep such code, |
| 8 | /// - comparisons "<= 0" and "> 0" are performed only on results of |
| 9 | /// signed functions/macros, |
| 10 | /// - hardcoded list of signed functions/macros with always non-negative |
| 11 | /// result is used to avoid false positives difficult to detect by other ways |
| 12 | /// |
| 13 | // Confidence: Average |
| 14 | // Copyright: (C) 2015 Andrzej Hajda, Samsung Electronics Co., Ltd. GPLv2. |
| 15 | // URL: http://coccinelle.lip6.fr/ |
| 16 | // Options: --all-includes |
| 17 | |
| 18 | virtual context |
| 19 | virtual org |
| 20 | virtual report |
| 21 | |
| 22 | @r_cmp@ |
| 23 | position p; |
| 24 | typedef bool, u8, u16, u32, u64; |
| 25 | {unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long, |
| 26 | size_t, bool, u8, u16, u32, u64} v; |
| 27 | expression e; |
| 28 | @@ |
| 29 | |
| 30 | \( v = e \| &v \) |
| 31 | ... |
| 32 | (\( v@p < 0 \| v@p <= 0 \| v@p >= 0 \| v@p > 0 \)) |
| 33 | |
| 34 | @r@ |
| 35 | position r_cmp.p; |
| 36 | typedef s8, s16, s32, s64; |
| 37 | {char, short, int, long, long long, ssize_t, s8, s16, s32, s64} vs; |
| 38 | expression c, e, v; |
| 39 | identifier f !~ "^(ata_id_queue_depth|btrfs_copy_from_user|dma_map_sg|dma_map_sg_attrs|fls|fls64|gameport_time|get_write_extents|nla_len|ntoh24|of_flat_dt_match|of_get_child_count|uart_circ_chars_pending|[A-Z0-9_]+)$"; |
| 40 | @@ |
| 41 | |
| 42 | ( |
| 43 | v = f(...)@vs; |
| 44 | ... when != v = e; |
| 45 | * (\( v@p <=@e 0 \| v@p >@e 0 \)) |
| 46 | ... when any |
| 47 | | |
| 48 | ( |
| 49 | (\( v@p < 0 \| v@p <= 0 \)) || ... || (\( v >= c \| v > c \)) |
| 50 | | |
| 51 | (\( v >= c \| v > c \)) || ... || (\( v@p < 0 \| v@p <= 0 \)) |
| 52 | | |
| 53 | (\( v@p >= 0 \| v@p > 0 \)) && ... && (\( v < c \| v <= c \)) |
| 54 | | |
| 55 | ((\( v < c \| v <= c \) && ... && \( v@p >= 0 \| v@p > 0 \))) |
| 56 | | |
| 57 | * (\( v@p <@e 0 \| v@p >=@e 0 \)) |
| 58 | ) |
| 59 | ) |
| 60 | |
| 61 | @script:python depends on org@ |
| 62 | p << r_cmp.p; |
| 63 | e << r.e; |
| 64 | @@ |
| 65 | |
| 66 | msg = "WARNING: Unsigned expression compared with zero: %s" % (e) |
| 67 | coccilib.org.print_todo(p[0], msg) |
| 68 | |
| 69 | @script:python depends on report@ |
| 70 | p << r_cmp.p; |
| 71 | e << r.e; |
| 72 | @@ |
| 73 | |
| 74 | msg = "WARNING: Unsigned expression compared with zero: %s" % (e) |
| 75 | coccilib.report.print_report(p[0], msg) |