[clang] dafc310 - [Sema] Emit a -Wformat warning for printf("%s", (void*)p)

Erik Pilkington via cfe-commits cfe-commits at lists.llvm.org
Fri Jul 10 12:10:34 PDT 2020


Author: Erik Pilkington
Date: 2020-07-10T15:10:24-04:00
New Revision: dafc3106d2069b806a10e072306a2196f1cda585

URL: https://github.com/llvm/llvm-project/commit/dafc3106d2069b806a10e072306a2196f1cda585
DIFF: https://github.com/llvm/llvm-project/commit/dafc3106d2069b806a10e072306a2196f1cda585.diff

LOG: [Sema] Emit a -Wformat warning for printf("%s", (void*)p)

Its dangerous to assume that the opaque pointer points to a null-terminated
string, and this has an easy fix (casting to char*).

rdar://62432331

Added: 
    

Modified: 
    clang/lib/AST/FormatString.cpp
    clang/test/Sema/format-strings.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/AST/FormatString.cpp b/clang/lib/AST/FormatString.cpp
index e9f6b88631af..83b952116a5e 100644
--- a/clang/lib/AST/FormatString.cpp
+++ b/clang/lib/AST/FormatString.cpp
@@ -419,7 +419,6 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const {
       QualType pointeeTy = PT->getPointeeType();
       if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>())
         switch (BT->getKind()) {
-          case BuiltinType::Void:
           case BuiltinType::Char_U:
           case BuiltinType::UChar:
           case BuiltinType::Char_S:

diff  --git a/clang/test/Sema/format-strings.c b/clang/test/Sema/format-strings.c
index 11acfcd1b9a6..e8cd478d2512 100644
--- a/clang/test/Sema/format-strings.c
+++ b/clang/test/Sema/format-strings.c
@@ -290,8 +290,11 @@ void test11(void *p, char *s) {
   printf("%0p", p); // expected-warning{{flag '0' results in undefined behavior with 'p' conversion specifier}}
   printf("%s", s); // no-warning
   printf("%+s", p); // expected-warning{{flag '+' results in undefined behavior with 's' conversion specifier}}
+                    // expected-warning at -1 {{format specifies type 'char *' but the argument has type 'void *'}}
   printf("% s", p); // expected-warning{{flag ' ' results in undefined behavior with 's' conversion specifier}}
+                    // expected-warning at -1 {{format specifies type 'char *' but the argument has type 'void *'}}
   printf("%0s", p); // expected-warning{{flag '0' results in undefined behavior with 's' conversion specifier}}
+                    // expected-warning at -1 {{format specifies type 'char *' but the argument has type 'void *'}}
 }
 
 void test12(char *b) {
@@ -707,3 +710,7 @@ void PR30481() {
   // This caused crashes due to invalid casts.
   printf(1 > 0); // expected-warning{{format string is not a string literal}} expected-warning{{incompatible integer to pointer conversion}} expected-note at format-strings.c:*{{passing argument to parameter here}} expected-note{{to avoid this}}
 }
+
+void test_printf_opaque_ptr(void *op) {
+  printf("%s", op); // expected-warning{{format specifies type 'char *' but the argument has type 'void *'}}
+}


        


More information about the cfe-commits mailing list