================ @@ -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 ---------------- AaronBallman wrote:
This doesn't seem like a particularly helpful test because it's catching a type mismatch rather than anything with format attributes. That said, I think functions that can be either valid C or C++ should be kept in the .c file and that file can get a C++-specific `RUN` line to test those situations. Then this .cpp file can be focused on constructs that exist in C++ but not C. WDYT? https://github.com/llvm/llvm-project/pull/70024 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits