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
bad_malloc(char * name)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
bad_malloc_wide(wchar_t * name)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
bad_alloca(char * name)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
bad_calloc(char * name)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
bad_realloc(char * old_name,char * name)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
intentional1(char * name)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
intentional2(char * name)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
intentional3(char * name)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
bad_indirect_alloc(char * name)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