Skip to content

Commit b1b87fb

Browse files
committed
address comments
1 parent 8c907cd commit b1b87fb

File tree

2 files changed

+68
-21
lines changed

2 files changed

+68
-21
lines changed

clang/lib/Analysis/UnsafeBufferUsage.cpp

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1925,7 +1925,15 @@ class UnsafeLibcFunctionCallGadget : public WarningGadget {
19251925
if (!CE || !CE->getDirectCallee())
19261926
return false;
19271927
const auto *FD = dyn_cast<FunctionDecl>(CE->getDirectCallee());
1928-
if (!FD || isa<CXXMethodDecl>(FD))
1928+
if (!FD)
1929+
return false;
1930+
1931+
bool IsGlobalAndNotInAnyNamespace =
1932+
FD->isGlobal() && !FD->getEnclosingNamespaceContext()->isNamespace();
1933+
1934+
// A libc function must either be in the std:: namespace or a global
1935+
// function that is not in any namespace:
1936+
if (!FD->isInStdNamespace() && !IsGlobalAndNotInAnyNamespace)
19291937
return false;
19301938
auto isSingleStringLiteralArg = false;
19311939
if (CE->getNumArgs() == 1) {

clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp

Lines changed: 59 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,16 @@
44
// RUN: -verify %s -x objective-c++
55
// RUN: %clang_cc1 -std=c++20 -Wno-all -Wunsafe-buffer-usage-in-libc-call \
66
// RUN: -verify %s
7+
// RUN: %clang_cc1 -std=c++20 -Wno-all -Wunsafe-buffer-usage-in-libc-call \
8+
// RUN: -verify %s -DTEST_STD_NS
79

810
typedef struct {} FILE;
11+
typedef unsigned int size_t;
12+
13+
#ifdef TEST_STD_NS
14+
namespace std {
15+
#endif
16+
917
void memcpy();
1018
void __asan_memcpy();
1119
void strcpy();
@@ -25,6 +33,11 @@ int sscanf(const char * buffer, const char * format, ... );
2533
int wprintf(const wchar_t* format, ... );
2634
int __asan_printf();
2735

36+
#ifdef TEST_STD_NS
37+
} //namespace std
38+
using namespace std;
39+
#endif
40+
2841
namespace std {
2942
template< class InputIt, class OutputIt >
3043
OutputIt copy( InputIt first, InputIt last,
@@ -51,10 +64,6 @@ namespace std {
5164

5265
typedef basic_string<char> string;
5366
typedef basic_string<wchar_t> wstring;
54-
55-
// C function under std:
56-
void memcpy();
57-
void strcpy();
5867
}
5968

6069
void f(char * p, char * q, std::span<char> s, std::span<char> s2) {
@@ -64,14 +73,16 @@ void f(char * p, char * q, std::span<char> s, std::span<char> s2) {
6473
aligned_char_ptr_t cp;
6574

6675
memcpy(); // expected-warning{{function 'memcpy' is unsafe}}
67-
std::memcpy(); // expected-warning{{function 'memcpy' is unsafe}}
6876
__builtin_memcpy(p, q, 64); // expected-warning{{function '__builtin_memcpy' is unsafe}}
6977
__builtin___memcpy_chk(p, q, 8, 64); // expected-warning{{function '__builtin___memcpy_chk' is unsafe}}
7078
__asan_memcpy(); // expected-warning{{function '__asan_memcpy' is unsafe}}
7179
strcpy(); // expected-warning{{function 'strcpy' is unsafe}}
72-
std::strcpy(); // expected-warning{{function 'strcpy' is unsafe}}
7380
strcpy_s(); // expected-warning{{function 'strcpy_s' is unsafe}}
7481
wcscpy_s(); // expected-warning{{function 'wcscpy_s' is unsafe}}
82+
#ifdef TEST_STD_NS
83+
std::strcpy(); // expected-warning{{function 'strcpy' is unsafe}}
84+
std::memcpy(); // expected-warning{{function 'memcpy' is unsafe}}
85+
#endif
7586

7687
/* Test printfs */
7788
fprintf((FILE*)p, "%s%d", p, *p); // expected-warning{{function 'fprintf' is unsafe}} expected-note{{string argument is not guaranteed to be null-terminated}}
@@ -145,31 +156,59 @@ void ff(char * p, char * q, std::span<char> s, std::span<char> s2) {
145156
#pragma clang diagnostic push
146157
#pragma clang diagnostic ignored "-Wunsafe-buffer-usage-in-libc-call"
147158
memcpy();
148-
std::memcpy();
149159
__builtin_memcpy(p, q, 64);
150160
__builtin___memcpy_chk(p, q, 8, 64);
151161
__asan_memcpy();
152162
strcpy();
163+
#ifdef TEST_STD_NS
153164
std::strcpy();
165+
std::memcpy();
166+
#endif
154167
strcpy_s();
155168
wcscpy_s();
156169
#pragma clang diagnostic pop
157170
}
158171

159172

160-
namespace CXXMethodNoWarn {
161-
struct StrBuff
173+
174+
// functions not in global scope or std:: namespace are not libc
175+
// functions regardless of their names:
176+
struct StrBuff
177+
{
178+
void strcpy();
179+
void strcpy(char* dst);
180+
void memcpy(void *dst, const void *src, size_t size);
181+
};
182+
183+
namespace NS {
184+
void strcpy();
185+
void strcpy(char* dst);
186+
void memcpy(void *dst, const void *src, size_t size);
187+
}
188+
189+
namespace std {
190+
// class methods even in std namespace cannot be libc functions:
191+
struct LibC
162192
{
163-
void strcpy() const;
164-
void strcpy(char* dst) const;
165-
void Strcpy(char* dst) const;
193+
void strcpy();
194+
void strcpy(char* dst);
195+
void memcpy(void *dst, const void *src, size_t size);
166196
};
197+
}
167198

168-
void test(const StrBuff& str)
169-
{
170-
char buff[64];
171-
str.strcpy();
172-
str.strcpy(buff);
173-
str.Strcpy(buff);
174-
}
175-
} // namespace CXXMethodNoWarn
199+
void test(StrBuff& str)
200+
{
201+
char buff[64];
202+
str.strcpy();
203+
str.strcpy(buff);
204+
str.memcpy(buff, buff, 64);
205+
NS::strcpy();
206+
NS::strcpy(buff);
207+
NS::memcpy(buff, buff, 64);
208+
209+
std::LibC LibC;
210+
211+
LibC.strcpy();
212+
LibC.strcpy(buff);
213+
LibC.memcpy(buff, buff, 64);
214+
}

0 commit comments

Comments
 (0)