1 // RUN: %clang_cc1 -std=c++20 -Wno-all -Wunsafe-buffer-usage \
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 \
8 typedef struct {} FILE;
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
, ... );
29 template< class InputIt
, class OutputIt
>
30 OutputIt
copy( InputIt first
, InputIt last
,
38 unsigned size_bytes();
40 iterator
begin() const noexcept
;
41 iterator
end() const noexcept
;
49 unsigned size_bytes();
52 typedef basic_string
<char> string
;
53 typedef basic_string
<wchar_t> wstring
;
55 // C function under std:
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}}
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
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
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}}
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
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"
146 __builtin_memcpy(p
, q
, 64);
147 __builtin___memcpy_chk(p
, q
, 8, 64);
153 #pragma clang diagnostic pop