Author: ziqingluo-90 Date: 2024-09-16T17:21:24-07:00 New Revision: 48498ec7a4ded9f1bf813051abdc54c3e5b66fa7
URL: https://github.com/llvm/llvm-project/commit/48498ec7a4ded9f1bf813051abdc54c3e5b66fa7 DIFF: https://github.com/llvm/llvm-project/commit/48498ec7a4ded9f1bf813051abdc54c3e5b66fa7.diff LOG: [-Wunsafe-buffer-usage] Fix a bug in "Re-land [-Wunsafe-buffer-usage] Warning Libc functions (#101583)" StringLiteral::getString() is not applicable to strings of wide characters. Added handling for that. (rdar://117182250) Added: Modified: clang/lib/Analysis/UnsafeBufferUsage.cpp clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp Removed: ################################################################################ diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp index a00b166a8b4f93..a16762244b1766 100644 --- a/clang/lib/Analysis/UnsafeBufferUsage.cpp +++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp @@ -560,13 +560,22 @@ static bool hasUnsafeFormatOrSArg(const CallExpr *Call, const Expr *&UnsafeArg, const Expr *Fmt = Call->getArg(FmtArgIdx); if (auto *SL = dyn_cast<StringLiteral>(Fmt->IgnoreParenImpCasts())) { - StringRef FmtStr = SL->getString(); + StringRef FmtStr; + + if (SL->getCharByteWidth() == 1) + FmtStr = SL->getString(); + else if (auto EvaledFmtStr = SL->tryEvaluateString(Ctx)) + FmtStr = *EvaledFmtStr; + else + goto CHECK_UNSAFE_PTR; + StringFormatStringHandler Handler(Call, FmtArgIdx, UnsafeArg); return analyze_format_string::ParsePrintfString( Handler, FmtStr.begin(), FmtStr.end(), Ctx.getLangOpts(), Ctx.getTargetInfo(), isKprintf); } +CHECK_UNSAFE_PTR: // If format is not a string literal, we cannot analyze the format string. // In this case, this call is considered unsafe if at least one argument // (including the format argument) is unsafe pointer. diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp index 8e777a7a51c994..25b6d8e9e22dc2 100644 --- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp +++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp @@ -20,6 +20,7 @@ int snwprintf_s( char* buffer, unsigned buf_size, const char* format, ... ); int vsnprintf( char* buffer, unsigned buf_size, const char* format, ... ); int sscanf_s(const char * buffer, const char * format, ...); int sscanf(const char * buffer, const char * format, ... ); +int wprintf(const wchar_t* format, ... ); int __asan_printf(); namespace std { @@ -83,9 +84,11 @@ void f(char * p, char * q, std::span<char> s, std::span<char> s2) { sscanf(p, "%s%d", "hello", *p); // expected-warning{{function 'sscanf' is unsafe}} sscanf_s(p, "%s%d", "hello", *p); // expected-warning{{function 'sscanf_s' is unsafe}} 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}} + wprintf(L"hello %s", p); // expected-warning{{function 'wprintf' is unsafe}} expected-note{{string argument is not guaranteed to be null-terminated}} char a[10], b[11]; int c[10]; + std::wstring WS; snprintf(a, sizeof(b), "%s", __PRETTY_FUNCTION__); // expected-warning{{function 'snprintf' is unsafe}} expected-note{{buffer pointer and size may not match}} snprintf((char*)c, sizeof(c), "%s", __PRETTY_FUNCTION__); // expected-warning{{function 'snprintf' is unsafe}} expected-note{{buffer pointer and size may not match}} @@ -95,6 +98,8 @@ void f(char * p, char * q, std::span<char> s, std::span<char> s2) { snprintf(s.data(), s.size_bytes(), "%s%d", __PRETTY_FUNCTION__, *p); // no warn snwprintf(s.data(), s.size_bytes(), "%s%d", __PRETTY_FUNCTION__, *p); // no warn snwprintf_s(s.data(), s.size_bytes(), "%s%d", __PRETTY_FUNCTION__, *p); // no warn + wprintf(L"hello %ls", L"world"); // no warn + wprintf(L"hello %ls", WS.c_str()); // no warn strlen("hello");// no warn __asan_printf();// a printf but no argument, so no warn } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits