[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / SemaCXX / warn-unsafe-buffer-usage-libc-functions.cpp
bloba7c19bcac16078cf23fa4395a7db046fd89f770b
1 // RUN: %clang_cc1 -std=c++20 -Wno-all -Wunsafe-buffer-usage \
2 // RUN: -verify %s
3 // RUN: %clang_cc1 -std=c++20 -Wno-all -Wunsafe-buffer-usage \
4 // RUN: -verify %s -x objective-c++
5 // RUN: %clang_cc1 -std=c++20 -Wno-all -Wunsafe-buffer-usage-in-libc-call \
6 // RUN: -verify %s
8 typedef struct {} FILE;
9 void memcpy();
10 void __asan_memcpy();
11 void strcpy();
12 void strcpy_s();
13 void wcscpy_s();
14 unsigned strlen( const char* str );
15 int fprintf( FILE* stream, const char* format, ... );
16 int printf( const char* format, ... );
17 int sprintf( char* buffer, const char* format, ... );
18 int swprintf( char* buffer, const char* format, ... );
19 int snprintf( char* buffer, unsigned buf_size, const char* format, ... );
20 int snwprintf( char* buffer, unsigned buf_size, const char* format, ... );
21 int snwprintf_s( char* buffer, unsigned buf_size, const char* format, ... );
22 int vsnprintf( char* buffer, unsigned buf_size, const char* format, ... );
23 int sscanf_s(const char * buffer, const char * format, ...);
24 int sscanf(const char * buffer, const char * format, ... );
25 int wprintf(const wchar_t* format, ... );
26 int __asan_printf();
28 namespace std {
29 template< class InputIt, class OutputIt >
30 OutputIt copy( InputIt first, InputIt last,
31 OutputIt d_first );
33 struct iterator{};
34 template<typename T>
35 struct span {
36 T * ptr;
37 T * data();
38 unsigned size_bytes();
39 unsigned size();
40 iterator begin() const noexcept;
41 iterator end() const noexcept;
44 template<typename T>
45 struct basic_string {
46 T* p;
47 T *c_str();
48 T *data();
49 unsigned size_bytes();
52 typedef basic_string<char> string;
53 typedef basic_string<wchar_t> wstring;
55 // C function under std:
56 void memcpy();
57 void strcpy();
60 void f(char * p, char * q, std::span<char> s, std::span<char> s2) {
61 typedef FILE * _Nullable aligned_file_ptr_t __attribute__((align_value(64)));
62 typedef char * _Nullable aligned_char_ptr_t __attribute__((align_value(64)));
63 aligned_file_ptr_t fp;
64 aligned_char_ptr_t cp;
66 memcpy(); // expected-warning{{function 'memcpy' is unsafe}}
67 std::memcpy(); // expected-warning{{function 'memcpy' is unsafe}}
68 __builtin_memcpy(p, q, 64); // expected-warning{{function '__builtin_memcpy' is unsafe}}
69 __builtin___memcpy_chk(p, q, 8, 64); // expected-warning{{function '__builtin___memcpy_chk' is unsafe}}
70 __asan_memcpy(); // expected-warning{{function '__asan_memcpy' is unsafe}}
71 strcpy(); // expected-warning{{function 'strcpy' is unsafe}}
72 std::strcpy(); // expected-warning{{function 'strcpy' is unsafe}}
73 strcpy_s(); // expected-warning{{function 'strcpy_s' is unsafe}}
74 wcscpy_s(); // expected-warning{{function 'wcscpy_s' is unsafe}}
76 /* Test printfs */
77 fprintf((FILE*)p, "%s%d", p, *p); // expected-warning{{function 'fprintf' is unsafe}} expected-note{{string argument is not guaranteed to be null-terminated}}
78 printf("%s%d", // expected-warning{{function 'printf' is unsafe}}
79 p, // expected-note{{string argument is not guaranteed to be null-terminated}} note attached to the unsafe argument
80 *p);
81 printf(cp, p, *p); // expected-warning{{function 'printf' is unsafe}} // expected-note{{string argument is not guaranteed to be null-terminated}}
82 sprintf(q, "%s%d", "hello", *p); // expected-warning{{function 'sprintf' is unsafe}} expected-note{{change to 'snprintf' for explicit bounds checking}}
83 swprintf(q, "%s%d", "hello", *p); // expected-warning{{function 'swprintf' is unsafe}} expected-note{{change to 'snprintf' for explicit bounds checking}}
84 snprintf(q, 10, "%s%d", "hello", *p); // expected-warning{{function 'snprintf' is unsafe}} expected-note{{buffer pointer and size may not match}}
85 snprintf(cp, 10, "%s%d", "hello", *p); // expected-warning{{function 'snprintf' is unsafe}} expected-note{{buffer pointer and size may not match}}
86 snprintf(s.data(), s2.size(), "%s%d", "hello", *p); // expected-warning{{function 'snprintf' is unsafe}} expected-note{{buffer pointer and size may not match}}
87 snwprintf(s.data(), s2.size(), "%s%d", "hello", *p); // expected-warning{{function 'snwprintf' is unsafe}} expected-note{{buffer pointer and size may not match}}
88 snwprintf_s( // expected-warning{{function 'snwprintf_s' is unsafe}}
89 s.data(), // expected-note{{buffer pointer and size may not match}} // note attached to the buffer
90 s2.size(),
91 "%s%d", "hello", *p);
92 vsnprintf(s.data(), s.size_bytes(), "%s%d", "hello", *p); // expected-warning{{function 'vsnprintf' is unsafe}} expected-note{{'va_list' is unsafe}}
93 sscanf(p, "%s%d", "hello", *p); // expected-warning{{function 'sscanf' is unsafe}}
94 sscanf_s(p, "%s%d", "hello", *p); // expected-warning{{function 'sscanf_s' is unsafe}}
95 fprintf((FILE*)p, "%P%d%p%i hello world %32s", *p, *p, p, *p, p); // expected-warning{{function 'fprintf' is unsafe}} expected-note{{string argument is not guaranteed to be null-terminated}}
96 fprintf(fp, "%P%d%p%i hello world %32s", *p, *p, p, *p, p); // expected-warning{{function 'fprintf' is unsafe}} expected-note{{string argument is not guaranteed to be null-terminated}}
97 wprintf(L"hello %s", p); // expected-warning{{function 'wprintf' is unsafe}} expected-note{{string argument is not guaranteed to be null-terminated}}
100 char a[10], b[11];
101 int c[10];
102 std::wstring WS;
104 snprintf(a, sizeof(b), "%s", __PRETTY_FUNCTION__); // expected-warning{{function 'snprintf' is unsafe}} expected-note{{buffer pointer and size may not match}}
105 snprintf((char*)c, sizeof(c), "%s", __PRETTY_FUNCTION__); // expected-warning{{function 'snprintf' is unsafe}} expected-note{{buffer pointer and size may not match}}
106 fprintf((FILE*)p, "%P%d%p%i hello world %32s", *p, *p, p, *p, "hello"); // no warn
107 fprintf(fp, "%P%d%p%i hello world %32s", *p, *p, p, *p, "hello"); // no warn
108 printf("%s%d", "hello", *p); // no warn
109 snprintf(s.data(), s.size_bytes(), "%s%d", "hello", *p); // no warn
110 snprintf(s.data(), s.size_bytes(), "%s%d", __PRETTY_FUNCTION__, *p); // no warn
111 snwprintf(s.data(), s.size_bytes(), "%s%d", __PRETTY_FUNCTION__, *p); // no warn
112 snwprintf_s(s.data(), s.size_bytes(), "%s%d", __PRETTY_FUNCTION__, *p); // no warn
113 wprintf(L"hello %ls", L"world"); // no warn
114 wprintf(L"hello %ls", WS.c_str()); // no warn
115 strlen("hello");// no warn
116 __asan_printf();// a printf but no argument, so no warn
119 void safe_examples(std::string s1, int *p) {
120 snprintf(s1.data(), s1.size_bytes(), "%s%d%s%p%s", __PRETTY_FUNCTION__, *p, "hello", p, s1.c_str()); // no warn
121 snprintf(s1.data(), s1.size_bytes(), s1.c_str(), __PRETTY_FUNCTION__, *p, "hello", s1.c_str()); // no warn
122 printf("%s%d%s%p%s", __PRETTY_FUNCTION__, *p, "hello", p, s1.c_str()); // no warn
123 printf(s1.c_str(), __PRETTY_FUNCTION__, *p, "hello", s1.c_str()); // no warn
124 fprintf((FILE*)0, "%s%d%s%p%s", __PRETTY_FUNCTION__, *p, "hello", p, s1.c_str()); // no warn
125 fprintf((FILE*)0, s1.c_str(), __PRETTY_FUNCTION__, *p, "hello", s1.c_str()); // no warn
127 char a[10];
129 snprintf(a, sizeof a, "%s%d%s%p%s", __PRETTY_FUNCTION__, *p, "hello", s1.c_str()); // no warn
130 snprintf(a, sizeof(decltype(a)), "%s%d%s%p%s", __PRETTY_FUNCTION__, *p, "hello", s1.c_str()); // no warn
131 snprintf(a, 10, "%s%d%s%p%s", __PRETTY_FUNCTION__, *p, "hello", s1.c_str()); // no warn
135 void g(char *begin, char *end, char *p, std::span<char> s) {
136 std::copy(begin, end, p); // no warn
137 std::copy(s.begin(), s.end(), s.begin()); // no warn
140 // warning gets turned off
141 void ff(char * p, char * q, std::span<char> s, std::span<char> s2) {
142 #pragma clang diagnostic push
143 #pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
144 memcpy();
145 std::memcpy();
146 __builtin_memcpy(p, q, 64);
147 __builtin___memcpy_chk(p, q, 8, 64);
148 __asan_memcpy();
149 strcpy();
150 std::strcpy();
151 strcpy_s();
152 wcscpy_s();
153 #pragma clang diagnostic pop