llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Vitaly Buka (vitalybuka)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/106649.diff


2 Files Affected:

- (modified) clang/lib/Sema/SemaDeclAttr.cpp (+14-14) 
- (modified) clang/test/Sema/attr-format-missing.c (+27-37) 


``````````diff
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 5166e61bb41d46..94d9ea5762fc17 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5339,9 +5339,9 @@ void Sema::DiagnoseMissingFormatAttributes(Stmt *Body,
 
   // Check if there are more than one format type found. In that case do not
   // emit diagnostic.
-  const FormatAttr *FirstAttr = MissingFormatAttributes[0];
+  const clang::IdentifierInfo *AttrType = 
MissingFormatAttributes[0]->getType();
   if (llvm::any_of(MissingFormatAttributes, [&](const FormatAttr *Attr) {
-        return FirstAttr->getType() != Attr->getType();
+        return AttrType != Attr->getType();
       }))
     return;
 
@@ -5416,15 +5416,18 @@ Sema::GetMissingFormatAttributes(Stmt *Body, const 
FunctionDecl *FDecl) {
     // If child expression is function, check if it is format function.
     // If it is, check if parent function misses format attributes.
 
+    unsigned int ChildFunctionFormatArgumentIndexOffset =
+        checkIfMethodHasImplicitObjectParameter(ChildFunction) ? 2 : 1;
+
+    if (!ChildFunction->hasAttr<FormatAttr>())
+      continue;
+
     // If child function is format function and format arguments are not
     // relevant to emit diagnostic, save only information about format type
     // (format index and first-to-check argument index are set to -1).
     // Information about format type is later used to determine if there are
     // more than one format type found.
 
-    unsigned int ChildFunctionFormatArgumentIndexOffset =
-        checkIfMethodHasImplicitObjectParameter(ChildFunction) ? 2 : 1;
-
     // Check if function has format attribute with forwarded format string.
     IdentifierInfo *AttrType;
     const ParmVarDecl *FormatArg;
@@ -5465,7 +5468,7 @@ Sema::GetMissingFormatAttributes(Stmt *Body, const 
FunctionDecl *FDecl) {
       continue;
 
     // Check if format string argument is parent function parameter.
-    unsigned int StringIndex = 0;
+    int StringIndex = 0;
     if (!llvm::any_of(FDecl->parameters(), [&](const ParmVarDecl *Param) {
           if (Param != FormatArg)
             return false;
@@ -5506,16 +5509,13 @@ Sema::GetMissingFormatAttributes(Stmt *Body, const 
FunctionDecl *FDecl) {
     }
 
     // Get first argument index
-    unsigned FirstToCheck = [&]() -> unsigned {
+    int FirstToCheck = [&]() -> unsigned {
       if (!FDecl->isVariadic())
         return 0;
-      const auto *FirstToCheckArg =
-          dyn_cast<DeclRefExpr>(Args[NumArgs - 1]->IgnoreParenCasts());
-      if (!FirstToCheckArg)
-        return 0;
-
-      if (FirstToCheckArg->getType().getCanonicalType() !=
-          Context.getBuiltinVaListType().getCanonicalType())
+      const auto *FirstToCheckArg = Args[NumArgs - 1]->IgnoreParenCasts();
+      if (!FirstToCheckArg ||
+          FirstToCheckArg->getType().getCanonicalType() !=
+              Context.getBuiltinVaListType().getCanonicalType())
         return 0;
       return NumOfParentFunctionParams + FunctionFormatArgumentIndexOffset;
     }();
diff --git a/clang/test/Sema/attr-format-missing.c 
b/clang/test/Sema/attr-format-missing.c
index 4f9e91eb1becbc..e887e11d767040 100644
--- a/clang/test/Sema/attr-format-missing.c
+++ b/clang/test/Sema/attr-format-missing.c
@@ -3,14 +3,11 @@
 // RUN: %clang_cc1 -fsyntax-only -x c++ -verify=expected,cpp_diagnostics 
-Wmissing-format-attribute %s
 // RUN: %clang_cc1 -fsyntax-only -x c++ -verify=expected,cpp_diagnostics 
-std=c++2b -Wmissing-format-attribute %s
 // RUN: %clang_cc1 -fsyntax-only -x c++ -verify=expected,cpp_diagnostics 
-std=c++23 -Wmissing-format-attribute %s
-// RUN: not %clang_cc1 -fsyntax-only -x c++ -Wmissing-format-attribute 
-fdiagnostics-parseable-fixits -triple x86_64-linux %s 2>&1 | FileCheck %s 
--check-prefixes=CHECK,CHECK-LIN64
-// RUN: not %clang_cc1 -fsyntax-only -x c++ -Wmissing-format-attribute 
-fdiagnostics-parseable-fixits -triple x86_64-windows %s 2>&1 | FileCheck %s 
--check-prefixes=CHECK
-// RUN: not %clang_cc1 -fsyntax-only -x c++ -Wmissing-format-attribute 
-fdiagnostics-parseable-fixits -triple i386-windows %s 2>&1 | FileCheck %s 
--check-prefixes=CHECK
-// RUN: not %clang_cc1 -fsyntax-only -x c++ -Wmissing-format-attribute 
-fdiagnostics-parseable-fixits -triple i386-windows %s 2>&1 | FileCheck %s 
--check-prefixes=CHECK
+// RUN: not %clang_cc1 -fsyntax-only -x c++ -Wmissing-format-attribute 
-fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
 
 #ifndef __cplusplus
-typedef unsigned short char16_t;
-typedef unsigned int char32_t;
+typedef __CHAR16_TYPE__ char16_t;
+typedef __CHAR32_TYPE__ char32_t;
 typedef __WCHAR_TYPE__ wchar_t;
 #endif
 
@@ -84,16 +81,16 @@ void f7(const char *out, ... /* args */) // #f7
 {
     va_list args;
 
-    vscanf(out, &args[0]); // 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, 
0)))"
+    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)))"
 }
 
 void f8(const char *out, ... /* args */) // #f8
 {
     va_list args;
 
-    vscanf(out, &args[0]); // expected-no-warning@#f8
-    vprintf(out, &args[0]); // expected-no-warning@#f8
+    vscanf(out, args); // expected-no-warning@#f8
+    vprintf(out, args); // expected-no-warning@#f8
 }
 
 void f9(const char out[], ... /* args */) // #f9
@@ -109,16 +106,18 @@ void f10(const wchar_t *out, ... /* args */) // #f10
 {
     va_list args;
     vscanf(out, args);
-#if __SIZEOF_WCHAR_T__ == 4
-                        // c_diagnostics-warning@-2 {{incompatible pointer 
types passing 'const wchar_t *' (aka 'const int *') to parameter of type 'const 
char *'}}
+#if (defined(__aarch64__) && !defined(_WIN64)) || (defined(__arm__) && 
!defined(_WIN32))
+                        // c_diagnostics-warning@-2 {{incompatible pointer 
types passing 'const wchar_t *' (aka 'const unsigned int *') to parameter of 
type 'const char *'}}
+#elif __SIZEOF_WCHAR_T__ == 4
+                        // c_diagnostics-warning@-4 {{incompatible pointer 
types passing 'const wchar_t *' (aka 'const int *') to parameter of type 'const 
char *'}}
 #else
-                        // c_diagnostics-warning@-4 {{incompatible pointer 
types passing 'const wchar_t *' (aka 'const unsigned short *') to parameter of 
type 'const char *'}}
+                        // c_diagnostics-warning@-6 {{incompatible pointer 
types passing 'const wchar_t *' (aka 'const unsigned short *') to parameter of 
type 'const char *'}}
 #endif
                         // c_diagnostics-note@#vscanf {{passing argument to 
parameter here}}
                         // c_diagnostics-warning@#f10 {{diagnostic behavior 
may be improved by adding the 'scanf' format attribute to the declaration of 
'f10'}}
-                        // cpp_diagnostics-error@-8 {{no matching function for 
call to 'vscanf'}}
-                        // cpp_diagnostics-note@#vscanf {{candidate function 
not viable: no known conversion from 'const wchar_t *' to 'const char *' for 
1st argument}}
                         // C-CHECK: 
fix-it:"{{.*}}":{[[@LINE-13]]:6-[[@LINE-13]]:6}:"__attribute__((format(scanf, 
1, 2)))"
+                        // cpp_diagnostics-error@-11 {{no matching function 
for call to 'vscanf'}}
+                        // cpp_diagnostics-note@#vscanf {{candidate function 
not viable: no known conversion from 'const wchar_t *' to 'const char *' for 
1st argument}}
 }
 
 void f11(const wchar_t *out, ... /* args */) // #f11
@@ -139,16 +138,18 @@ void f13(const wchar_t *out, ... /* args */) // #f13
 {
     va_list args;
     vscanf(out, args);
-#if __SIZEOF_WCHAR_T__ == 4
-                        // c_diagnostics-warning@-2 {{incompatible pointer 
types passing 'const wchar_t *' (aka 'const int *') to parameter of type 'const 
char *'}}
-#else
-                        // c_diagnostics-warning@-4 {{incompatible pointer 
types passing 'const wchar_t *' (aka 'const unsigned short *') to parameter of 
type 'const char *'}}
+#if (defined(__aarch64__) && !defined(_WIN64)) || (defined(__arm__) && 
!defined(_WIN32))
+                        // c_diagnostics-warning@-2 {{incompatible pointer 
types passing 'const wchar_t *' (aka 'const unsigned int *') to parameter of 
type 'const char *'}}
+#elif (defined(__x86_64__) && !defined(_WIN64)) || __SIZEOF_WCHAR_T__ == 4
+                        // c_diagnostics-warning@-4 {{incompatible pointer 
types passing 'const wchar_t *' (aka 'const int *') to parameter of type 'const 
char *'}}
+#elif __SIZEOF_WCHAR_T__ == 2
+                        // c_diagnostics-warning@-6 {{incompatible pointer 
types passing 'const wchar_t *' (aka 'const unsigned short *') to parameter of 
type 'const char *'}}
 #endif
                         // c_diagnostics-note@#vscanf {{passing argument to 
parameter here}}
-                        // cpp_diagnostics-error@-7 {{no matching function for 
call to 'vscanf'}}
+                        // cpp_diagnostics-error@-9 {{no matching function for 
call to 'vscanf'}}
                         // cpp_diagnostics-note@#vscanf {{candidate function 
not viable: no known conversion from 'const wchar_t *' to 'const char *' for 
1st argument}}
                         // expected-warning@#f13 {{diagnostic behavior may be 
improved by adding the 'scanf' format attribute to the declaration of 'f13'}}
-                        // CHECK: 
fix-it:"{{.*}}":{[[@LINE-13]]:6-[[@LINE-13]]:6}:"__attribute__((format(scanf, 
1, 2)))"
+                        // CHECK: 
fix-it:"{{.*}}":{[[@LINE-15]]:6-[[@LINE-15]]:6}:"__attribute__((format(scanf, 
1, 2)))"
     vscanf((const char *) out, args);
     vscanf((char *) out, args);
 }
@@ -327,9 +328,9 @@ void f33(char *out, va_list args) // #f33
 void f34(char *out, ... /* args */) // #f34
 {
     va_list args;
-    scanf(out, args); // expected-no-warning@#f34
+    scanf(out, args);
     {
-        scanf(out, args); // expected-no-warning@#f34
+        scanf(out, args);
     }
 }
 
@@ -341,7 +342,7 @@ void f35(char* ch, const char *out, ... /* args */) // #f35
     int a;
     printf(out, a); // expected-warning@#f35 {{diagnostic behavior may be 
improved by adding the 'printf' format attribute to the declaration of 'f35'}}
                     // CHECK: 
fix-it:"{{.*}}":{[[@LINE-7]]:6-[[@LINE-7]]:6}:"__attribute__((format(printf, 2, 
0)))"
-    printf(out, 1); // no warning because first command above emitted same 
warning with same fix-it text
+    printf(out, 1); // no warning because first command above emitted same 
warning and fix-it
     printf(out, args); // expected-warning@#f35 {{diagnostic behavior may be 
improved by adding the 'printf' format attribute to the declaration of 'f35'}}
                        // CHECK: 
fix-it:"{{.*}}":{[[@LINE-10]]:6-[[@LINE-10]]:6}:"__attribute__((format(printf, 
2, 3)))"
 }
@@ -387,17 +388,6 @@ void f40(char *out, ... /* args */) // #f40
 void f41(char *out, ... /* args */) // #f41
 {
     va_list args;
-    char *ch;
-    vscanf("%s", ch);
-#if defined(__x86_64__) && defined(__linux__)
-                        // c_diagnostics-warning@-2 {{incompatible pointer 
types passing 'char *' to parameter of type 'struct __va_list_tag *'}}
-                        // c_diagnostics-note@#vscanf {{passing argument to 
parameter here}}
-                        // cpp_diagnostics-error@-4 {{no matching function for 
call to 'vscanf'}}
-                        // cpp_diagnostics-note@#vscanf {{candidate function 
not viable: no known conversion from 'char *' to '__va_list_tag *' for 2nd 
argument}}
-#endif
-    vprintf(out, args);
-#if defined(__x86_64__) && defined(__linux__)
-                        // cpp_diagnostics-warning@#f41 {{diagnostic behavior 
may be improved by adding the 'printf' format attribute to the declaration of 
'f41'}}
-                        // CHECK-LIN64: 
fix-it:"{{.*}}":{[[@LINE-14]]:6-[[@LINE-14]]:6}:"__attribute__((format(printf, 
1, 2)))"
-#endif
+    vscanf("%s", args); // expected-no-warning@#f41
+    vprintf(out, args); // expected-no-warning@#f41
 }

``````````

</details>


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

Reply via email to