================
@@ -0,0 +1,259 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wmissing-format-attribute %s
+// RUN: %clang_cc1 -fsyntax-only -Wmissing-format-attribute 
-fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+// RUN: %clang_cc1 -fsyntax-only -x c++ -verify -Wmissing-format-attribute %s
+// RUN: %clang_cc1 -fsyntax-only -x c++ -verify -std=c++23 
-Wmissing-format-attribute %s
+// RUN: %clang_cc1 -fsyntax-only -x c++ -Wmissing-format-attribute 
-fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
+
+#ifndef __cplusplus
+typedef __CHAR16_TYPE__ char16_t;
+typedef __CHAR32_TYPE__ char32_t;
+typedef __WCHAR_TYPE__ wchar_t;
+#endif
+
+typedef __SIZE_TYPE__ size_t;
+typedef __builtin_va_list va_list;
+
+__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 *, size_t, const char *, va_list); // #vsnprintf
+
+#ifndef __cplusplus
+int vwscanf(const wchar_t *, va_list); // #vwscanf
+#endif
+
+__attribute__((__format__(__scanf__, 1, 4)))
+void f1(char *out, const size_t len, const char *format, ... /* args */) // #f1
+{
+    va_list args;
+    vsnprintf(out, len, format, args);
+}
+
+__attribute__((__format__(__printf__, 1, 4)))
+void f2(char *out, const size_t len, const char *format, ... /* args */) // #f2
+{
+    va_list args;
+    vsnprintf(out, len, format, args); // expected-warning@#f2 {{diagnostic 
behavior may be improved by adding the 'printf' format attribute to the 
declaration of 'f2'}}
+                                       // CHECK: 
fix-it:"{{.*}}":{[[@LINE-4]]:6-[[@LINE-4]]:6}:"__attribute__((format(printf, 3, 
4)))"
+                                       // expected-note@-2 {{'printf' format 
function}}
+}
+
+void f3(char *out, va_list args) // #f3
+{
+    vprintf(out, args); // expected-warning@#f3 {{diagnostic behavior may be 
improved by adding the 'printf' format attribute to the declaration of 'f3'}}
+                        // CHECK: 
fix-it:"{{.*}}":{[[@LINE-3]]:6-[[@LINE-3]]:6}:"__attribute__((format(printf, 1, 
0)))"
+                        // expected-note@-2 {{'printf' format function}}
+}
+
+void f4(char* out, ... /* args */) // #f4
+{
+    va_list args;
+    vprintf("test", args);
+
+    const char *ch;
+    vprintf(ch, args);
+}
+
+void f5(va_list args) // #f5
+{
+    char *ch;
+    vscanf(ch, args);
+}
+
+void f6(char *out, va_list args) // #f6
+{
+    char *ch;
+    vprintf(ch, args);
+    vprintf("test", args);
+    vprintf(out, args); // expected-warning@#f6 {{diagnostic behavior may be 
improved by adding the 'printf' format attribute to the declaration of 'f6'}}
+                        // CHECK: 
fix-it:"{{.*}}":{[[@LINE-6]]:6-[[@LINE-6]]:6}:"__attribute__((format(printf, 1, 
0)))"
+                        // expected-note@-2 {{'printf' format function}}
+}
+
+void f7(const char *out, ... /* args */) // #f7
+{
+    va_list args;
+
+    vscanf(out, args); // expected-warning@#f7 {{diagnostic behavior may be 
improved by adding the 'scanf' format attribute to the declaration of 'f7'}}
+                       // CHECK: 
fix-it:"{{.*}}":{[[@LINE-5]]:6-[[@LINE-5]]:6}:"__attribute__((format(scanf, 1, 
2)))"
+                       // expected-note@-2 {{'scanf' format function}}
+}
+
+void f8(const char *out, ... /* args */) // #f8
+{
+    va_list args;
+
+    vscanf(out, args);
+    vprintf(out, args);
----------------
aaronpuchert wrote:

Here I don't see why we shouldn't warn on each of these calls. If the first 
call triggers a warning, why does the second call make it go away? This might 
be seen as leading to contradictory suggestions, but this function doesn't 
really make sense: the same arguments can't be both arguments to `printf` and 
`scanf`, unless the list is empty.

https://github.com/llvm/llvm-project/pull/105479
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to