[clang] [clang] Catch missing format attributes (PR #70024)
Budimir Aranđelović via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 12 06:51:10 PDT 2024
================
@@ -0,0 +1,303 @@
+// RUN: %clang_cc1 -fsyntax-only -verify=expected,beforeCxx2b -Wmissing-format-attribute %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++2b -Wmissing-format-attribute %s
+// RUN: %clang_cc1 -fsyntax-only -verify -std=c++23 -Wmissing-format-attribute %s
+
+typedef __SIZE_TYPE__ size_t;
+typedef __builtin_va_list va_list;
+
+namespace std
+{
+ template<class Elem> struct basic_string_view {};
+ template<class Elem> struct basic_string {
+ const Elem *c_str() const noexcept;
+ basic_string(const basic_string_view<Elem> SW);
+ };
+
+ using string = basic_string<char>;
+ using wstring = basic_string<wchar_t>;
+ using string_view = basic_string_view<char>;
+ using wstring_view = basic_string_view<wchar_t>;
+}
+
+__attribute__((__format__(__printf__, 1, 2)))
+int printf(const char *, ...); // #printf
+
+__attribute__((__format__(__scanf__, 1, 2)))
+int scanf(const char *, ...); // #scanf
+
+__attribute__((__format__(__printf__, 1, 0)))
+int vprintf(const char *, va_list); // #vprintf
+
+__attribute__((__format__(__scanf__, 1, 0)))
+int vscanf(const char *, va_list); // #vscanf
+
+__attribute__((__format__(__printf__, 2, 0)))
+int vsprintf(char *, const char *, va_list); // #vsprintf
+
+__attribute__((__format__(__printf__, 3, 0)))
+int vsnprintf(char *ch, size_t, const char *, va_list); // #vsnprintf
+
+void f1(const std::string &str, ... /* args */) // #f1
+{
+ va_list args;
+ vscanf(str.c_str(), args); // no warning
+ vprintf(str.c_str(), args); // no warning
+}
+
+__attribute__((format(printf, 1, 2))) // expected-error {{format argument not a string type}}
+void f2(const std::string &str, ... /* args */); // #f2
+
+void f3(std::string_view str, ... /* args */) // #f3
+{
+ va_list args;
+ vscanf(std::string(str).c_str(), args); // no warning
+ vprintf(std::string(str).c_str(), args); // no warning
+}
+
+__attribute__((format(printf, 1, 2))) // expected-error {{format argument not a string type}}
+void f4(std::string_view str, ... /* args */); // #f4
+
+void f5(const std::wstring &str, ... /* args */) // #f5
+{
+ va_list args;
+ vscanf((const char *)str.c_str(), args); // no warning
+ vprintf((const char *)str.c_str(), args); // no warning
+}
+
+__attribute__((format(printf, 1, 2))) // expected-error {{format argument not a string type}}
+void f6(const std::wstring &str, ... /* args */); // #f6
+
+void f7(std::wstring_view str, ... /* args */) // #f7
+{
+ va_list args;
+ vscanf((const char *) std::wstring(str).c_str(), args); // no warning
+ vprintf((const char *) std::wstring(str).c_str(), args); // no warning
+}
+
+__attribute__((format(printf, 1, 2))) // expected-error {{format argument not a string type}}
+void f8(std::wstring_view str, ... /* args */); // #f8
+
+void f9(const wchar_t *out, ... /* args */) // #f9
+{
+ va_list args;
+ vprintf(out, args); // expected-error {{no matching function for call to 'vprintf'}}
+ // expected-note@#vprintf {{candidate function not viable: no known conversion from 'const wchar_t *' to 'const char *' for 1st argument}}
+ vscanf((const char *) out, args); // expected-warning@#f9 {{diagnostic behavior may be improved by adding the 'scanf' format attribute to the declaration of 'f9'}}
+ // CHECK-FIXES: __attribute__((format(scanf, 1, 2)))
+ vscanf((char *) out, args); // expected-warning@#f9 {{diagnostic behavior may be improved by adding the 'scanf' format attribute to the declaration of 'f9'}}
+ // CHECK-FIXES: __attribute__((format(scanf, 1, 2)))
+}
+
+__attribute__((format(printf, 1, 2))) // expected-error {{format argument not a string type}}
+void f10(const wchar_t *out, ... /* args */); // #f10
+
+void f11(const char16_t *out, ... /* args */) // #f11
----------------
budimirarandjelovicsyrmia wrote:
It makes sense. I agree.
https://github.com/llvm/llvm-project/pull/70024
More information about the cfe-commits
mailing list