1 | // RUN: %check_clang_tidy %s bugprone-misplaced-operator-in-strlen-in-alloc %t |
2 | |
3 | typedef __typeof(sizeof(int)) size_t; |
4 | void *malloc(size_t); |
5 | void *alloca(size_t); |
6 | void *calloc(size_t, size_t); |
7 | void *realloc(void *, size_t); |
8 | |
9 | size_t strlen(const char *); |
10 | size_t strnlen(const char *, size_t); |
11 | size_t strnlen_s(const char *, size_t); |
12 | |
13 | typedef unsigned wchar_t; |
14 | |
15 | size_t wcslen(const wchar_t *); |
16 | size_t wcsnlen(const wchar_t *, size_t); |
17 | size_t wcsnlen_s(const wchar_t *, size_t); |
18 | |
19 | void bad_malloc(char *name) { |
20 | char *new_name = (char *)malloc(strlen(name + 1)); |
21 | // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: addition operator is applied to the argument of strlen |
22 | // CHECK-FIXES: {{^ char \*new_name = \(char \*\)malloc\(}}strlen(name) + 1{{\);$}} |
23 | new_name = (char *)malloc(strnlen(name + 1, 10)); |
24 | // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: addition operator is applied to the argument of strnlen |
25 | // CHECK-FIXES: {{^ new_name = \(char \*\)malloc\(}}strnlen(name, 10) + 1{{\);$}} |
26 | new_name = (char *)malloc(strnlen_s(name + 1, 10)); |
27 | // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: addition operator is applied to the argument of strnlen_s |
28 | // CHECK-FIXES: {{^ new_name = \(char \*\)malloc\(}}strnlen_s(name, 10) + 1{{\);$}} |
29 | } |
30 | |
31 | void bad_malloc_wide(wchar_t *name) { |
32 | wchar_t *new_name = (wchar_t *)malloc(wcslen(name + 1)); |
33 | // CHECK-MESSAGES: :[[@LINE-1]]:34: warning: addition operator is applied to the argument of wcslen |
34 | // CHECK-FIXES: {{^ wchar_t \*new_name = \(wchar_t \*\)malloc\(}}wcslen(name) + 1{{\);$}} |
35 | new_name = (wchar_t *)malloc(wcsnlen(name + 1, 10)); |
36 | // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: addition operator is applied to the argument of wcsnlen |
37 | // CHECK-FIXES: {{^ new_name = \(wchar_t \*\)malloc\(}}wcsnlen(name, 10) + 1{{\);$}} |
38 | new_name = (wchar_t *)malloc(wcsnlen_s(name + 1, 10)); |
39 | // CHECK-MESSAGES: :[[@LINE-1]]:25: warning: addition operator is applied to the argument of wcsnlen_s |
40 | // CHECK-FIXES: {{^ new_name = \(wchar_t \*\)malloc\(}}wcsnlen_s(name, 10) + 1{{\);$}} |
41 | } |
42 | |
43 | void bad_alloca(char *name) { |
44 | char *new_name = (char *)alloca(strlen(name + 1)); |
45 | // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: addition operator is applied to the argument of strlen |
46 | // CHECK-FIXES: {{^ char \*new_name = \(char \*\)alloca\(}}strlen(name) + 1{{\);$}} |
47 | } |
48 | |
49 | void bad_calloc(char *name) { |
50 | char *new_names = (char *)calloc(2, strlen(name + 1)); |
51 | // CHECK-MESSAGES: :[[@LINE-1]]:29: warning: addition operator is applied to the argument of strlen |
52 | // CHECK-FIXES: {{^ char \*new_names = \(char \*\)calloc\(2, }}strlen(name) + 1{{\);$}} |
53 | } |
54 | |
55 | void bad_realloc(char *old_name, char *name) { |
56 | char *new_name = (char *)realloc(old_name, strlen(name + 1)); |
57 | // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: addition operator is applied to the argument of strlen |
58 | // CHECK-FIXES: {{^ char \*new_name = \(char \*\)realloc\(old_name, }}strlen(name) + 1{{\);$}} |
59 | } |
60 | |
61 | void intentional1(char *name) { |
62 | char *new_name = (char *)malloc(strlen(name + 1) + 1); |
63 | // CHECK-MESSAGES-NOT: :[[@LINE-1]]:28: warning: addition operator is applied to the argument of strlen |
64 | // We have + 1 outside as well so we assume this is intentional |
65 | } |
66 | |
67 | void intentional2(char *name) { |
68 | char *new_name = (char *)malloc(strlen(name + 2)); |
69 | // CHECK-MESSAGES-NOT: :[[@LINE-1]]:28: warning: addition operator is applied to the argument of strlen |
70 | // Only give warning for + 1, not + 2 |
71 | } |
72 | |
73 | void intentional3(char *name) { |
74 | char *new_name = (char *)malloc(strlen((name + 1))); |
75 | // CHECK-MESSAGES-NOT: :[[@LINE-1]]:28: warning: addition operator is applied to the argument of strlen |
76 | // If expression is in extra parentheses, consider it as intentional |
77 | } |
78 | |
79 | void (*(*const alloc_ptr)(size_t)) = malloc; |
80 | |
81 | void bad_indirect_alloc(char *name) { |
82 | char *new_name = (char *)alloc_ptr(strlen(name + 1)); |
83 | // CHECK-MESSAGES: :[[@LINE-1]]:28: warning: addition operator is applied to the argument of strlen |
84 | // CHECK-FIXES: {{^ char \*new_name = \(char \*\)alloc_ptr\(}}strlen(name) + 1{{\);$}} |
85 | } |
86 | |