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