Nathan-Huckleberry updated this revision to Diff 216699.
Nathan-Huckleberry added a comment.
- Warn when -Wformat-pedantic is set
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D66186/new/
https://reviews.llvm.org/D66186
Files:
clang/lib/AST/FormatString.cpp
clang/lib/Sema/SemaChecking.cpp
clang/test/FixIt/format.m
clang/test/Sema/format-strings-enum-fixed-type.cpp
clang/test/Sema/format-strings-pedantic.c
clang/test/Sema/format-strings.c
Index: clang/test/Sema/format-strings.c
===================================================================
--- clang/test/Sema/format-strings.c
+++ clang/test/Sema/format-strings.c
@@ -277,8 +277,8 @@
void should_understand_small_integers() {
printf("%hhu", (short) 10); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'short'}}
- printf("%hu\n", (unsigned char) 1); // expected-warning{{format specifies type 'unsigned short' but the argument has type 'unsigned char'}}
- printf("%hu\n", (uint8_t)1); // expected-warning{{format specifies type 'unsigned short' but the argument has type 'uint8_t'}}
+ printf("%hu\n", (unsigned char)1); // no-warning
+ printf("%hu\n", (uint8_t)1); // no-warning
}
void test11(void *p, char *s) {
Index: clang/test/Sema/format-strings-pedantic.c
===================================================================
--- /dev/null
+++ clang/test/Sema/format-strings-pedantic.c
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fsyntax-only -verify -Wformat -Wformat-pedantic -isystem %S/Inputs %s
+
+#include <stdarg.h>
+#include <stddef.h>
+#define __need_wint_t
+#include <stddef.h> // For wint_t and wchar_t
+
+typedef struct _FILE FILE;
+int fprintf(FILE *, const char *restrict, ...);
+int printf(const char *restrict, ...);
+int snprintf(char *restrict, size_t, const char *restrict, ...);
+int sprintf(char *restrict, const char *restrict, ...);
+int vasprintf(char **, const char *, va_list);
+int asprintf(char **, const char *, ...);
+int vfprintf(FILE *, const char *restrict, va_list);
+int vprintf(const char *restrict, va_list);
+int vsnprintf(char *, size_t, const char *, va_list);
+int vsprintf(char *restrict, const char *restrict, va_list);
+
+int vscanf(const char *restrict format, va_list arg);
+
+typedef unsigned char uint8_t;
+
+void should_understand_small_integers() {
+ printf("%hhu", (short)10); // expected-warning{{format specifies type 'unsigned char' but the argument has type 'short'}}
+ printf("%hu\n", (unsigned char)1); // expected-warning{{format specifies type 'unsigned short' but the argument has type 'unsigned char'}}
+ printf("%hu\n", (uint8_t)1); // expected-warning{{format specifies type 'unsigned short' but the argument has type 'uint8_t' (aka 'unsigned char')}}
+}
Index: clang/test/Sema/format-strings-enum-fixed-type.cpp
===================================================================
--- clang/test/Sema/format-strings-enum-fixed-type.cpp
+++ clang/test/Sema/format-strings-enum-fixed-type.cpp
@@ -80,9 +80,9 @@
printf("%hhd", CharConstant); // no-warning
// This is not correct but it is safe. We warn because '%hd' shows intent.
- printf("%hd", input); // expected-warning{{format specifies type 'short' but the argument has underlying type 'char'}}
- printf("%hd", CharConstant); // expected-warning{{format specifies type 'short'}}
-
+ printf("%hd", input); // no-warning
+ printf("%hd", CharConstant); // no-warning
+
// This is not correct but it matches the promotion rules (and is safe).
printf("%d", input); // no-warning
printf("%d", CharConstant); // no-warning
Index: clang/test/FixIt/format.m
===================================================================
--- clang/test/FixIt/format.m
+++ clang/test/FixIt/format.m
@@ -205,9 +205,7 @@
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%f"
// CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:16}:"(unichar)"
- NSLog(@"%C", (char)0x260300); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'char'}}
- // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c"
- // CHECK-NOT: fix-it:"{{.*}}":{[[@LINE-2]]:16-[[@LINE-2]]:22}:"(unichar)"
+ NSLog(@"%C", (char)0x260300);
NSLog(@"%C", 'a'); // expected-warning{{format specifies type 'unichar' (aka 'unsigned short') but the argument has type 'char'}}
// CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:13}:"%c"
Index: clang/lib/Sema/SemaChecking.cpp
===================================================================
--- clang/lib/Sema/SemaChecking.cpp
+++ clang/lib/Sema/SemaChecking.cpp
@@ -8077,8 +8077,7 @@
ExprTy = TET->getUnderlyingExpr()->getType();
}
- const analyze_printf::ArgType::MatchKind Match =
- AT.matchesType(S.Context, ExprTy);
+ analyze_printf::ArgType::MatchKind Match = AT.matchesType(S.Context, ExprTy);
bool Pedantic = Match == analyze_printf::ArgType::NoMatchPedantic;
if (Match == analyze_printf::ArgType::Match)
return true;
@@ -8098,9 +8097,14 @@
// function.
if (ICE->getType() == S.Context.IntTy ||
ICE->getType() == S.Context.UnsignedIntTy) {
- // All further checking is done on the subexpression.
- if (AT.matchesType(S.Context, ExprTy))
- return true;
+ // All further checking is done on the subexpression
+ Match = AT.matchesType(S.Context, ExprTy);
+ if (Match) {
+ if (Match == analyze_printf::ArgType::NoMatchPedantic)
+ Pedantic = true;
+ else
+ return true;
+ }
}
}
} else if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E)) {
Index: clang/lib/AST/FormatString.cpp
===================================================================
--- clang/lib/AST/FormatString.cpp
+++ clang/lib/AST/FormatString.cpp
@@ -386,6 +386,8 @@
case BuiltinType::SChar:
case BuiltinType::Char_U:
case BuiltinType::UChar:
+ if (T == C.UnsignedShortTy || T == C.ShortTy)
+ return NoMatchPedantic;
return T == C.UnsignedCharTy || T == C.SignedCharTy ? Match
: NoMatch;
case BuiltinType::Short:
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits