From dafc3106d2069b806a10e072306a2196f1cda585 Mon Sep 17 00:00:00 2001 From: Erik Pilkington Date: Fri, 10 Jul 2020 13:22:11 -0400 Subject: [PATCH] [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 --- clang/lib/AST/FormatString.cpp | 1 - clang/test/Sema/format-strings.c | 7 +++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/clang/lib/AST/FormatString.cpp b/clang/lib/AST/FormatString.cpp index e9f6b88631a..83b952116a5 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()) 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 11acfcd1b9a..e8cd478d251 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@-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@-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@-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@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 *'}} +} -- 2.11.0