[clang] [clang] Catch missing format attributes (PR #105479)

Aaron Puchert via cfe-commits cfe-commits at lists.llvm.org
Sat Jun 7 16:05:37 PDT 2025


================
@@ -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 at -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 at -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 at -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 at -2 {{'scanf' format function}}
+}
+
+void f8(const char *out, ... /* args */) // #f8
+{
+    va_list args;
+
+    vscanf(out, args);
+    vprintf(out, args);
+}
+
+void f9(const char out[], ... /* args */) // #f9
+{
+    va_list args;
+    char *ch;
+    vprintf(ch, args);
+    vsprintf(ch, out, args); // expected-warning@#f9 {{diagnostic behavior may be improved by adding the 'printf' format attribute to the declaration of 'f9'}}
+                             // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:6-[[@LINE-6]]:6}:"__attribute__((format(printf, 1, 2)))"
+                             // expected-note at -2 {{'printf' format function}}
+}
+
+#ifndef __cplusplus
+void f10(const wchar_t *out, ... /* args */) // #f10
+{
+    va_list args;
+    vwscanf(out, args);
+}
+#endif
+
+void f11(const char *out) // #f11
+{
+    va_list args;
+    vscanf(out, args); // expected-warning@#f11 {{diagnostic behavior may be improved by adding the 'scanf' format attribute to the declaration of 'f11'}}
+                       // CHECK: fix-it:"{{.*}}":{[[@LINE-4]]:6-[[@LINE-4]]:6}:"__attribute__((format(scanf, 1, 0)))"
+                       // expected-note at -2 {{'scanf' format function}}
+}
+
+void f12(char* out) // #f12
+{
+    va_list args;
+    const char* ch;
+    vsprintf(out, ch, args);
+    vprintf(out, args); // expected-warning@#f12 {{diagnostic behavior may be improved by adding the 'printf' format attribute to the declaration of 'f12'}}
+                        // CHECK: fix-it:"{{.*}}":{[[@LINE-6]]:6-[[@LINE-6]]:6}:"__attribute__((format(printf, 1, 0)))"
+                        // expected-note at -2 {{'printf' format function}}
+}
+
+void f13(const char *out, ... /* args */) // #f13
+{
+    va_list args;
+    printf(out, args);
+}
+
+void f14(char *out, ... /* args */) // #f14
+{
+    va_list args;
+    vscanf(out, args);
+    vprintf(out, args);
+}
+
+void f15(char *out, ... /* args */) // #f15
+{
+    va_list args;
+    vscanf(out, args);
+    {
+        vprintf(out, args);
+    }
+}
+
+void f16(char *out, va_list args) // #f16
+{
+    {
----------------
aaronpuchert wrote:

The blocks seem to be leftovers from an earlier version where you walked the function body and unpacked `CompoundStmt`s. Now this doesn't make so much sense anymore, so I'd drop them and then drop duplicate test cases.

https://github.com/llvm/llvm-project/pull/105479


More information about the cfe-commits mailing list