r373774 - [Sema] Split out -Wformat-type-confusion from -Wformat-pedantic
Erik Pilkington via cfe-commits
cfe-commits at lists.llvm.org
Fri Oct 4 12:20:27 PDT 2019
Author: epilk
Date: Fri Oct 4 12:20:27 2019
New Revision: 373774
URL: http://llvm.org/viewvc/llvm-project?rev=373774&view=rev
Log:
[Sema] Split out -Wformat-type-confusion from -Wformat-pedantic
The warnings now in -Wformat-type-confusion don't align with how we interpret
'pedantic' in clang, and don't belong in -pedantic.
Differential revision: https://reviews.llvm.org/D67775
Added:
cfe/trunk/test/Sema/format-type-confusion.c
Modified:
cfe/trunk/include/clang/AST/FormatString.h
cfe/trunk/include/clang/Basic/DiagnosticGroups.td
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/AST/FormatString.cpp
cfe/trunk/lib/Sema/SemaChecking.cpp
cfe/trunk/test/Sema/format-bool.c
cfe/trunk/test/Sema/format-strings-pedantic.c
Modified: cfe/trunk/include/clang/AST/FormatString.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/FormatString.h?rev=373774&r1=373773&r2=373774&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/FormatString.h (original)
+++ cfe/trunk/include/clang/AST/FormatString.h Fri Oct 4 12:20:27 2019
@@ -251,7 +251,21 @@ public:
enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CPointerTy,
AnyCharTy, CStrTy, WCStrTy, WIntTy };
- enum MatchKind { NoMatch = 0, Match = 1, NoMatchPedantic };
+ /// How well a given conversion specifier matches its argument.
+ enum MatchKind {
+ /// The conversion specifier and the argument types are incompatible. For
+ /// instance, "%d" and float.
+ NoMatch = 0,
+ /// The conversion specifier and the argument type are compatible. For
+ /// instance, "%d" and _Bool.
+ Match = 1,
+ /// The conversion specifier and the argument type are disallowed by the C
+ /// standard, but are in practice harmless. For instance, "%p" and int*.
+ NoMatchPedantic,
+ /// The conversion specifier and the argument type are compatible, but still
+ /// seems likely to be an error. For instance, "%hd" and _Bool.
+ NoMatchTypeConfusion,
+ };
private:
const Kind K;
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=373774&r1=373773&r2=373774&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Fri Oct 4 12:20:27 2019
@@ -780,6 +780,7 @@ def FormatSecurity : DiagGroup<"format-s
def FormatNonStandard : DiagGroup<"format-non-iso">;
def FormatY2K : DiagGroup<"format-y2k">;
def FormatPedantic : DiagGroup<"format-pedantic">;
+def FormatTypeConfusion : DiagGroup<"format-type-confusion">;
def Format : DiagGroup<"format",
[FormatExtraArgs, FormatZeroLength, NonNull,
FormatSecurity, FormatY2K, FormatInvalidSpecifier]>,
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=373774&r1=373773&r2=373774&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Fri Oct 4 12:20:27 2019
@@ -8092,16 +8092,17 @@ def warn_format_conversion_argument_type
"%select{type|underlying type}2 %1">,
InGroup<Format>;
def warn_format_conversion_argument_type_mismatch_pedantic : Extension<
- "format specifies type %0 but the argument has "
- "%select{type|underlying type}2 %1">,
+ warn_format_conversion_argument_type_mismatch.Text>,
InGroup<FormatPedantic>;
+def warn_format_conversion_argument_type_mismatch_confusion : Warning<
+ warn_format_conversion_argument_type_mismatch.Text>,
+ InGroup<FormatTypeConfusion>, DefaultIgnore;
def warn_format_argument_needs_cast : Warning<
"%select{values of type|enum values with underlying type}2 '%0' should not "
"be used as format arguments; add an explicit cast to %1 instead">,
InGroup<Format>;
def warn_format_argument_needs_cast_pedantic : Warning<
- "%select{values of type|enum values with underlying type}2 '%0' should not "
- "be used as format arguments; add an explicit cast to %1 instead">,
+ warn_format_argument_needs_cast.Text>,
InGroup<FormatPedantic>, DefaultIgnore;
def warn_printf_positional_arg_exceeds_data_args : Warning <
"data argument position '%0' exceeds the number of data arguments (%1)">,
Modified: cfe/trunk/lib/AST/FormatString.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/FormatString.cpp?rev=373774&r1=373773&r2=373774&view=diff
==============================================================================
--- cfe/trunk/lib/AST/FormatString.cpp (original)
+++ cfe/trunk/lib/AST/FormatString.cpp Fri Oct 4 12:20:27 2019
@@ -389,7 +389,7 @@ ArgType::matchesType(ASTContext &C, Qual
case BuiltinType::UChar:
case BuiltinType::Bool:
if (T == C.UnsignedShortTy || T == C.ShortTy)
- return NoMatchPedantic;
+ return NoMatchTypeConfusion;
return T == C.UnsignedCharTy || T == C.SignedCharTy ? Match
: NoMatch;
case BuiltinType::Short:
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=373774&r1=373773&r2=373774&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Fri Oct 4 12:20:27 2019
@@ -8172,9 +8172,7 @@ CheckPrintfHandler::checkFormatExpr(cons
return true;
}
- const analyze_printf::ArgType::MatchKind Match =
- AT.matchesType(S.Context, ExprTy);
- bool Pedantic = Match == analyze_printf::ArgType::NoMatchPedantic;
+ analyze_printf::ArgType::MatchKind Match = AT.matchesType(S.Context, ExprTy);
if (Match == analyze_printf::ArgType::Match)
return true;
@@ -8198,8 +8196,9 @@ CheckPrintfHandler::checkFormatExpr(cons
AT.matchesType(S.Context, ExprTy);
if (ImplicitMatch == analyze_printf::ArgType::Match)
return true;
- if (ImplicitMatch == analyze_printf::ArgType::NoMatchPedantic)
- Pedantic = true;
+ if (ImplicitMatch == ArgType::NoMatchPedantic ||
+ ImplicitMatch == ArgType::NoMatchTypeConfusion)
+ Match = ImplicitMatch;
}
}
} else if (const CharacterLiteral *CL = dyn_cast<CharacterLiteral>(E)) {
@@ -8261,7 +8260,7 @@ CheckPrintfHandler::checkFormatExpr(cons
if ((CastTyName == "NSInteger" || CastTyName == "NSUInteger") &&
(AT.isSizeT() || AT.isPtrdiffT()) &&
AT.matchesType(S.Context, CastTy))
- Pedantic = true;
+ Match = ArgType::NoMatchPedantic;
IntendedTy = CastTy;
ShouldNotPrintDirectly = true;
}
@@ -8281,10 +8280,20 @@ CheckPrintfHandler::checkFormatExpr(cons
CharSourceRange SpecRange = getSpecifierRange(StartSpecifier, SpecifierLen);
if (IntendedTy == ExprTy && !ShouldNotPrintDirectly) {
- unsigned Diag =
- Pedantic
- ? diag::warn_format_conversion_argument_type_mismatch_pedantic
- : diag::warn_format_conversion_argument_type_mismatch;
+ unsigned Diag;
+ switch (Match) {
+ case ArgType::Match: llvm_unreachable("expected non-matching");
+ case ArgType::NoMatchPedantic:
+ Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
+ break;
+ case ArgType::NoMatchTypeConfusion:
+ Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
+ break;
+ case ArgType::NoMatch:
+ Diag = diag::warn_format_conversion_argument_type_mismatch;
+ break;
+ }
+
// In this case, the specifier is wrong and should be changed to match
// the argument.
EmitFormatDiagnostic(S.PDiag(Diag)
@@ -8340,7 +8349,7 @@ CheckPrintfHandler::checkFormatExpr(cons
Name = TypedefTy->getDecl()->getName();
else
Name = CastTyName;
- unsigned Diag = Pedantic
+ unsigned Diag = Match == ArgType::NoMatchPedantic
? diag::warn_format_argument_needs_cast_pedantic
: diag::warn_format_argument_needs_cast;
EmitFormatDiagnostic(S.PDiag(Diag) << Name << IntendedTy << IsEnum
@@ -8367,10 +8376,19 @@ CheckPrintfHandler::checkFormatExpr(cons
switch (S.isValidVarArgType(ExprTy)) {
case Sema::VAK_Valid:
case Sema::VAK_ValidInCXX11: {
- unsigned Diag =
- Pedantic
- ? diag::warn_format_conversion_argument_type_mismatch_pedantic
- : diag::warn_format_conversion_argument_type_mismatch;
+ unsigned Diag;
+ switch (Match) {
+ case ArgType::Match: llvm_unreachable("expected non-matching");
+ case ArgType::NoMatchPedantic:
+ Diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;
+ break;
+ case ArgType::NoMatchTypeConfusion:
+ Diag = diag::warn_format_conversion_argument_type_mismatch_confusion;
+ break;
+ case ArgType::NoMatch:
+ Diag = diag::warn_format_conversion_argument_type_mismatch;
+ break;
+ }
EmitFormatDiagnostic(
S.PDiag(Diag) << AT.getRepresentativeTypeName(S.Context) << ExprTy
Modified: cfe/trunk/test/Sema/format-bool.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-bool.c?rev=373774&r1=373773&r2=373774&view=diff
==============================================================================
--- cfe/trunk/test/Sema/format-bool.c (original)
+++ cfe/trunk/test/Sema/format-bool.c Fri Oct 4 12:20:27 2019
@@ -1,8 +1,8 @@
// RUN: %clang_cc1 -xc %s -verify -DBOOL=_Bool
// RUN: %clang_cc1 -xc++ %s -verify -DBOOL=bool
// RUN: %clang_cc1 -xobjective-c %s -verify -DBOOL=_Bool
-// RUN: %clang_cc1 -xc %s -verify -DBOOL=_Bool -Wformat-pedantic -DPEDANTIC
-// RUN: %clang_cc1 -xc++ %s -verify -DBOOL=bool -Wformat-pedantic -DPEDANTIC
+// RUN: %clang_cc1 -xc %s -verify -DBOOL=_Bool -Wformat-type-confusion -DTYPE_CONF
+// RUN: %clang_cc1 -xc++ %s -verify -DBOOL=bool -Wformat-type-confusion -DTYPE_CONF
__attribute__((format(__printf__, 1, 2)))
int p(const char *fmt, ...);
@@ -22,13 +22,13 @@ BOOL b;
int main() {
p("%d", b);
p("%hd", b);
-#ifdef PEDANTIC
+#ifdef TYPE_CONF
// expected-warning at -2 {{format specifies type 'short' but the argument has type}}
#endif
p("%hhd", b);
p("%u", b);
p("%hu", b);
-#ifdef PEDANTIC
+#ifdef TYPE_CONF
// expected-warning at -2 {{format specifies type 'unsigned short' but the argument has type}}
#endif
p("%hhu", b);
Modified: cfe/trunk/test/Sema/format-strings-pedantic.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-strings-pedantic.c?rev=373774&r1=373773&r2=373774&view=diff
==============================================================================
--- cfe/trunk/test/Sema/format-strings-pedantic.c (original)
+++ cfe/trunk/test/Sema/format-strings-pedantic.c Fri Oct 4 12:20:27 2019
@@ -1,10 +1,20 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wformat -Wformat-pedantic -isystem %S/Inputs %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wno-format -Wformat-pedantic %s
+// RUN: %clang_cc1 -xobjective-c -fblocks -fsyntax-only -verify -Wno-format -Wformat-pedantic %s
+// RUN: %clang_cc1 -xc++ -fsyntax-only -verify -Wno-format -Wformat-pedantic %s
+__attribute__((format(printf, 1, 2)))
int printf(const char *restrict, ...);
-typedef unsigned char uint8_t;
+int main() {
+ printf("%p", (int *)0); // expected-warning {{format specifies type 'void *' but the argument has type 'int *'}}
+ printf("%p", (void *)0);
-void print_char_as_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')}}
+#ifdef __OBJC__
+ printf("%p", ^{}); // expected-warning {{format specifies type 'void *' but the argument has type 'void (^)(void)'}}
+ printf("%p", (id)0); // expected-warning {{format specifies type 'void *' but the argument has type 'id'}}
+#endif
+
+#ifdef __cplusplus
+ printf("%p", nullptr); // expected-warning {{format specifies type 'void *' but the argument has type 'nullptr_t'}}
+#endif
}
Added: cfe/trunk/test/Sema/format-type-confusion.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/format-type-confusion.c?rev=373774&view=auto
==============================================================================
--- cfe/trunk/test/Sema/format-type-confusion.c (added)
+++ cfe/trunk/test/Sema/format-type-confusion.c Fri Oct 4 12:20:27 2019
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -triple x86_64-apple-darwin9.0 -fsyntax-only -verify -Wno-format -Wformat-type-confusion %s
+
+__attribute__((format(__printf__, 1, 2)))
+int printf(const char *msg, ...);
+
+#define FMT "%hd %hu %d %u %hhd %hhu %c"
+
+int main() {
+ _Bool b = 0;
+ printf(FMT,
+ b, // expected-warning {{format specifies type 'short' but the argument has type '_Bool'}}
+ b, // expected-warning {{format specifies type 'unsigned short' but the argument has type '_Bool'}}
+ b, b, b, b, b);
+
+ unsigned char uc = 0;
+ printf(FMT,
+ uc, // expected-warning {{format specifies type 'short' but the argument has type 'unsigned char'}}
+ uc, // expected-warning {{format specifies type 'unsigned short' but the argument has type 'unsigned char'}}
+ uc, uc, uc, uc, uc);
+
+ signed char sc = 0;
+ printf(FMT,
+ sc, // expected-warning {{format specifies type 'short' but the argument has type 'signed char'}}
+ sc, // expected-warning {{format specifies type 'unsigned short' but the argument has type 'signed char'}}
+ sc, sc, sc, sc, sc);
+}
More information about the cfe-commits
mailing list