<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">Thanks.<div class=""><br class=""></div><div class="">Looks like there could be another one:</div><div class=""><br class=""></div><div class=""><div class="">      } else {</div><div class="">         // In this case, the expression could be printed using a different</div><div class="">         // specifier, but we've decided that the specifier is probably correct </div><div class="">         // and we should cast instead. Just use the normal warning message.</div><div class="">         EmitFormatDiagnostic(</div><div class="">           S.PDiag(diag::warn_format_conversion_argument_type_mismatch)</div><div class="">             << AT.getRepresentativeTypeName(S.Context) << ExprTy << IsEnum</div><div class="">             << E->getSourceRange(),</div><div class="">           E->getLocStart(), /*IsStringLocation*/false,</div><div class="">           SpecRange, Hints);</div><div class="">       }</div><div class=""><br class=""></div><div class="">I'll take a look at fixing it later today.</div><div class=""><br class=""></div><div class=""><br class=""></div><div><blockquote type="cite" class=""><div class="">On Mar 4, 2015, at 9:21 AM, Daniel Jasper <<a href="mailto:djasper@google.com" class="">djasper@google.com</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">There are some cases that weren't correctly put into the new FormatPedantic group, but instead reported through the normal Format group. Fixed some in r231242. Could you double-check that there aren't more incorrect classifications?</div><div class="gmail_extra"><br class=""><div class="gmail_quote">On Wed, Mar 4, 2015 at 4:12 AM, Seth Cantrell <span dir="ltr" class=""><<a href="mailto:seth.cantrell@gmail.com" target="_blank" class="">seth.cantrell@gmail.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: socantre<br class="">
Date: Tue Mar  3 21:12:10 2015<br class="">
New Revision: 231211<br class="">
<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=231211&view=rev" target="_blank" class="">http://llvm.org/viewvc/llvm-project?rev=231211&view=rev</a><br class="">
Log:<br class="">
Add a format warning for "%p" with non-void* args<br class="">
<br class="">
GCC -pedantic produces a format warning when the "%p" specifier is used with<br class="">
arguments that are not void*. It's useful for portability to be able to<br class="">
catch such warnings with clang as well. The warning is off by default in<br class="">
both gcc and with this patch. This patch enables it either when extensions<br class="">
are disabled with -pedantic, or with the specific flag -Wformat-pedantic.<br class="">
<br class="">
The C99 and C11 specs do appear to require arguments corresponding to 'p'<br class="">
specifiers to be void*: "If any argument is not the correct type for the<br class="">
corresponding conversion specification, the behavior is undefined."<br class="">
[7.19.6.1 p9], and of the 'p' format specifier "The argument shall be a<br class="">
pointer to void." [7.19.6.1 p8]<br class="">
<br class="">
Both printf and scanf format checking are covered.<br class="">
<br class="">
Modified:<br class="">
    cfe/trunk/include/clang/Analysis/Analyses/FormatString.h<br class="">
    cfe/trunk/include/clang/Basic/DiagnosticGroups.td<br class="">
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br class="">
    cfe/trunk/lib/Analysis/FormatString.cpp<br class="">
    cfe/trunk/lib/Sema/SemaChecking.cpp<br class="">
    cfe/trunk/test/SemaCXX/format-strings-0x.cpp<br class="">
<br class="">
Modified: cfe/trunk/include/clang/Analysis/Analyses/FormatString.h<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/FormatString.h?rev=231211&r1=231210&r2=231211&view=diff" target="_blank" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/Analyses/FormatString.h?rev=231211&r1=231210&r2=231211&view=diff</a><br class="">
==============================================================================<br class="">
--- cfe/trunk/include/clang/Analysis/Analyses/FormatString.h (original)<br class="">
+++ cfe/trunk/include/clang/Analysis/Analyses/FormatString.h Tue Mar  3 21:12:10 2015<br class="">
@@ -231,6 +231,9 @@ class ArgType {<br class="">
 public:<br class="">
   enum Kind { UnknownTy, InvalidTy, SpecificTy, ObjCPointerTy, CPointerTy,<br class="">
               AnyCharTy, CStrTy, WCStrTy, WIntTy };<br class="">
+<br class="">
+  enum MatchKind { NoMatch = 0, Match = 1, NoMatchPedantic };<br class="">
+<br class="">
 private:<br class="">
   const Kind K;<br class="">
   QualType T;<br class="">
@@ -254,7 +257,7 @@ public:<br class="">
     return Res;<br class="">
   }<br class="">
<br class="">
-  bool matchesType(ASTContext &C, QualType argTy) const;<br class="">
+  MatchKind matchesType(ASTContext &C, QualType argTy) const;<br class="">
<br class="">
   QualType getRepresentativeType(ASTContext &C) const;<br class="">
<br class="">
<br class="">
Modified: cfe/trunk/include/clang/Basic/DiagnosticGroups.td<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=231211&r1=231210&r2=231211&view=diff" target="_blank" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticGroups.td?rev=231211&r1=231210&r2=231211&view=diff</a><br class="">
==============================================================================<br class="">
--- cfe/trunk/include/clang/Basic/DiagnosticGroups.td (original)<br class="">
+++ cfe/trunk/include/clang/Basic/DiagnosticGroups.td Tue Mar  3 21:12:10 2015<br class="">
@@ -551,6 +551,7 @@ def FormatInvalidSpecifier : DiagGroup<"<br class="">
 def FormatSecurity : DiagGroup<"format-security">;<br class="">
 def FormatNonStandard : DiagGroup<"format-non-iso">;<br class="">
 def FormatY2K : DiagGroup<"format-y2k">;<br class="">
+def FormatPedantic : DiagGroup<"format-pedantic">;<br class="">
 def Format : DiagGroup<"format",<br class="">
                        [FormatExtraArgs, FormatZeroLength, NonNull,<br class="">
                         FormatSecurity, FormatY2K, FormatInvalidSpecifier]>,<br class="">
<br class="">
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=231211&r1=231210&r2=231211&view=diff" target="_blank" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=231211&r1=231210&r2=231211&view=diff</a><br class="">
==============================================================================<br class="">
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)<br class="">
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Tue Mar  3 21:12:10 2015<br class="">
@@ -6644,6 +6644,10 @@ def warn_format_conversion_argument_type<br class="">
   "format specifies type %0 but the argument has "<br class="">
   "%select{type|underlying type}2 %1">,<br class="">
   InGroup<Format>;<br class="">
+def warn_format_conversion_argument_type_mismatch_pedantic : Extension<<br class="">
+  "format specifies type %0 but the argument has "<br class="">
+  "%select{type|underlying type}2 %1">,<br class="">
+  InGroup<FormatPedantic>;<br class="">
 def warn_format_argument_needs_cast : Warning<<br class="">
   "%select{values of type|enum values with underlying type}2 '%0' should not "<br class="">
   "be used as format arguments; add an explicit cast to %1 instead">,<br class="">
<br class="">
Modified: cfe/trunk/lib/Analysis/FormatString.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/FormatString.cpp?rev=231211&r1=231210&r2=231211&view=diff" target="_blank" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/FormatString.cpp?rev=231211&r1=231210&r2=231211&view=diff</a><br class="">
==============================================================================<br class="">
--- cfe/trunk/lib/Analysis/FormatString.cpp (original)<br class="">
+++ cfe/trunk/lib/Analysis/FormatString.cpp Tue Mar  3 21:12:10 2015<br class="">
@@ -256,16 +256,17 @@ clang::analyze_format_string::ParseLengt<br class="">
 // Methods on ArgType.<br class="">
 //===----------------------------------------------------------------------===//<br class="">
<br class="">
-bool ArgType::matchesType(ASTContext &C, QualType argTy) const {<br class="">
+clang::analyze_format_string::ArgType::MatchKind<br class="">
+ArgType::matchesType(ASTContext &C, QualType argTy) const {<br class="">
   if (Ptr) {<br class="">
     // It has to be a pointer.<br class="">
     const PointerType *PT = argTy->getAs<PointerType>();<br class="">
     if (!PT)<br class="">
-      return false;<br class="">
+      return NoMatch;<br class="">
<br class="">
     // We cannot write through a const qualified pointer.<br class="">
     if (PT->getPointeeType().isConstQualified())<br class="">
-      return false;<br class="">
+      return NoMatch;<br class="">
<br class="">
     argTy = PT->getPointeeType();<br class="">
   }<br class="">
@@ -275,8 +276,8 @@ bool ArgType::matchesType(ASTContext &C,<br class="">
       llvm_unreachable("ArgType must be valid");<br class="">
<br class="">
     case UnknownTy:<br class="">
-      return true;<br class="">
-<br class="">
+      return Match;<br class="">
+<br class="">
     case AnyCharTy: {<br class="">
       if (const EnumType *ETy = argTy->getAs<EnumType>())<br class="">
         argTy = ETy->getDecl()->getIntegerType();<br class="">
@@ -289,18 +290,18 @@ bool ArgType::matchesType(ASTContext &C,<br class="">
           case BuiltinType::SChar:<br class="">
           case BuiltinType::UChar:<br class="">
           case BuiltinType::Char_U:<br class="">
-            return true;<br class="">
+            return Match;<br class="">
         }<br class="">
-      return false;<br class="">
+      return NoMatch;<br class="">
     }<br class="">
-<br class="">
+<br class="">
     case SpecificTy: {<br class="">
       if (const EnumType *ETy = argTy->getAs<EnumType>())<br class="">
         argTy = ETy->getDecl()->getIntegerType();<br class="">
       argTy = C.getCanonicalType(argTy).getUnqualifiedType();<br class="">
<br class="">
       if (T == argTy)<br class="">
-        return true;<br class="">
+        return Match;<br class="">
       // Check for "compatible types".<br class="">
       if (const BuiltinType *BT = argTy->getAs<BuiltinType>())<br class="">
         switch (BT->getKind()) {<br class="">
@@ -309,32 +310,33 @@ bool ArgType::matchesType(ASTContext &C,<br class="">
           case BuiltinType::Char_S:<br class="">
           case BuiltinType::SChar:<br class="">
           case BuiltinType::Char_U:<br class="">
-          case BuiltinType::UChar:<br class="">
-            return T == C.UnsignedCharTy || T == C.SignedCharTy;<br class="">
+          case BuiltinType::UChar:<br class="">
+            return T == C.UnsignedCharTy || T == C.SignedCharTy ? Match<br class="">
+                                                                : NoMatch;<br class="">
           case BuiltinType::Short:<br class="">
-            return T == C.UnsignedShortTy;<br class="">
+            return T == C.UnsignedShortTy ? Match : NoMatch;<br class="">
           case BuiltinType::UShort:<br class="">
-            return T == C.ShortTy;<br class="">
+            return T == C.ShortTy ? Match : NoMatch;<br class="">
           case BuiltinType::Int:<br class="">
-            return T == C.UnsignedIntTy;<br class="">
+            return T == C.UnsignedIntTy ? Match : NoMatch;<br class="">
           case BuiltinType::UInt:<br class="">
-            return T == C.IntTy;<br class="">
+            return T == C.IntTy ? Match : NoMatch;<br class="">
           case BuiltinType::Long:<br class="">
-            return T == C.UnsignedLongTy;<br class="">
+            return T == C.UnsignedLongTy ? Match : NoMatch;<br class="">
           case BuiltinType::ULong:<br class="">
-            return T == C.LongTy;<br class="">
+            return T == C.LongTy ? Match : NoMatch;<br class="">
           case BuiltinType::LongLong:<br class="">
-            return T == C.UnsignedLongLongTy;<br class="">
+            return T == C.UnsignedLongLongTy ? Match : NoMatch;<br class="">
           case BuiltinType::ULongLong:<br class="">
-            return T == C.LongLongTy;<br class="">
+            return T == C.LongLongTy ? Match : NoMatch;<br class="">
         }<br class="">
-      return false;<br class="">
+      return NoMatch;<br class="">
     }<br class="">
<br class="">
     case CStrTy: {<br class="">
       const PointerType *PT = argTy->getAs<PointerType>();<br class="">
       if (!PT)<br class="">
-        return false;<br class="">
+        return NoMatch;<br class="">
       QualType pointeeTy = PT->getPointeeType();<br class="">
       if (const BuiltinType *BT = pointeeTy->getAs<BuiltinType>())<br class="">
         switch (BT->getKind()) {<br class="">
@@ -343,50 +345,56 @@ bool ArgType::matchesType(ASTContext &C,<br class="">
           case BuiltinType::UChar:<br class="">
           case BuiltinType::Char_S:<br class="">
           case BuiltinType::SChar:<br class="">
-            return true;<br class="">
+            return Match;<br class="">
           default:<br class="">
             break;<br class="">
         }<br class="">
<br class="">
-      return false;<br class="">
+      return NoMatch;<br class="">
     }<br class="">
<br class="">
     case WCStrTy: {<br class="">
       const PointerType *PT = argTy->getAs<PointerType>();<br class="">
       if (!PT)<br class="">
-        return false;<br class="">
+        return NoMatch;<br class="">
       QualType pointeeTy =<br class="">
         C.getCanonicalType(PT->getPointeeType()).getUnqualifiedType();<br class="">
-      return pointeeTy == C.getWideCharType();<br class="">
+      return pointeeTy == C.getWideCharType() ? Match : NoMatch;<br class="">
     }<br class="">
-<br class="">
+<br class="">
     case WIntTy: {<br class="">
-<br class="">
+<br class="">
       QualType PromoArg =<br class="">
         argTy->isPromotableIntegerType()<br class="">
           ? C.getPromotedIntegerType(argTy) : argTy;<br class="">
-<br class="">
+<br class="">
       QualType WInt = C.getCanonicalType(C.getWIntType()).getUnqualifiedType();<br class="">
       PromoArg = C.getCanonicalType(PromoArg).getUnqualifiedType();<br class="">
-<br class="">
+<br class="">
       // If the promoted argument is the corresponding signed type of the<br class="">
       // wint_t type, then it should match.<br class="">
       if (PromoArg->hasSignedIntegerRepresentation() &&<br class="">
           C.getCorrespondingUnsignedType(PromoArg) == WInt)<br class="">
-        return true;<br class="">
+        return Match;<br class="">
<br class="">
-      return WInt == PromoArg;<br class="">
+      return WInt == PromoArg ? Match : NoMatch;<br class="">
     }<br class="">
<br class="">
     case CPointerTy:<br class="">
-      return argTy->isPointerType() || argTy->isObjCObjectPointerType() ||<br class="">
-             argTy->isBlockPointerType() || argTy->isNullPtrType();<br class="">
+      if (argTy->isVoidPointerType()) {<br class="">
+        return Match;<br class="">
+      } if (argTy->isPointerType() || argTy->isObjCObjectPointerType() ||<br class="">
+            argTy->isBlockPointerType() || argTy->isNullPtrType()) {<br class="">
+        return NoMatchPedantic;<br class="">
+      } else {<br class="">
+        return NoMatch;<br class="">
+      }<br class="">
<br class="">
     case ObjCPointerTy: {<br class="">
       if (argTy->getAs<ObjCObjectPointerType>() ||<br class="">
           argTy->getAs<BlockPointerType>())<br class="">
-        return true;<br class="">
-<br class="">
+        return Match;<br class="">
+<br class="">
       // Handle implicit toll-free bridging.<br class="">
       if (const PointerType *PT = argTy->getAs<PointerType>()) {<br class="">
         // Things such as CFTypeRef are really just opaque pointers<br class="">
@@ -395,9 +403,9 @@ bool ArgType::matchesType(ASTContext &C,<br class="">
         // structs can be toll-free bridged, we just accept them all.<br class="">
         QualType pointee = PT->getPointeeType();<br class="">
         if (pointee->getAsStructureType() || pointee->isVoidType())<br class="">
-          return true;<br class="">
+          return Match;<br class="">
       }<br class="">
-      return false;<br class="">
+      return NoMatch;<br class="">
     }<br class="">
   }<br class="">
<br class="">
<br class="">
Modified: cfe/trunk/lib/Sema/SemaChecking.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=231211&r1=231210&r2=231211&view=diff" target="_blank" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=231211&r1=231210&r2=231211&view=diff</a><br class="">
==============================================================================<br class="">
--- cfe/trunk/lib/Sema/SemaChecking.cpp (original)<br class="">
+++ cfe/trunk/lib/Sema/SemaChecking.cpp Tue Mar  3 21:12:10 2015<br class="">
@@ -3669,8 +3669,11 @@ CheckPrintfHandler::checkFormatExpr(cons<br class="">
     ExprTy = TET->getUnderlyingExpr()->getType();<br class="">
   }<br class="">
<br class="">
-  if (AT.matchesType(S.Context, ExprTy))<br class="">
+  analyze_printf::ArgType::MatchKind match = AT.matchesType(S.Context, ExprTy);<br class="">
+<br class="">
+  if (match == analyze_printf::ArgType::Match) {<br class="">
     return true;<br class="">
+  }<br class="">
<br class="">
   // Look through argument promotions for our error message's reported type.<br class="">
   // This includes the integral and floating promotions, but excludes array<br class="">
@@ -3848,15 +3851,18 @@ CheckPrintfHandler::checkFormatExpr(cons<br class="">
     // arguments here.<br class="">
     switch (S.isValidVarArgType(ExprTy)) {<br class="">
     case Sema::VAK_Valid:<br class="">
-    case Sema::VAK_ValidInCXX11:<br class="">
+    case Sema::VAK_ValidInCXX11: {<br class="">
+      unsigned diag = diag::warn_format_conversion_argument_type_mismatch;<br class="">
+      if (match == analyze_printf::ArgType::NoMatchPedantic) {<br class="">
+        diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;<br class="">
+      }<br class="">
+<br class="">
       EmitFormatDiagnostic(<br class="">
-        S.PDiag(diag::warn_format_conversion_argument_type_mismatch)<br class="">
-          << AT.getRepresentativeTypeName(S.Context) << ExprTy << IsEnum<br class="">
-          << CSR<br class="">
-          << E->getSourceRange(),<br class="">
-        E->getLocStart(), /*IsStringLocation*/false, CSR);<br class="">
+          S.PDiag(diag) << AT.getRepresentativeTypeName(S.Context) << ExprTy<br class="">
+                        << IsEnum << CSR << E->getSourceRange(),<br class="">
+          E->getLocStart(), /*IsStringLocation*/ false, CSR);<br class="">
       break;<br class="">
-<br class="">
+    }<br class="">
     case Sema::VAK_Undefined:<br class="">
     case Sema::VAK_MSVCUndefined:<br class="">
       EmitFormatDiagnostic(<br class="">
@@ -3988,13 +3994,13 @@ bool CheckScanfHandler::HandleScanfSpeci<br class="">
                            FixItHint::CreateRemoval(R));<br class="">
     }<br class="">
   }<br class="">
-<br class="">
+<br class="">
   if (!FS.consumesDataArgument()) {<br class="">
     // FIXME: Technically specifying a precision or field width here<br class="">
     // makes no sense.  Worth issuing a warning at some point.<br class="">
     return true;<br class="">
   }<br class="">
-<br class="">
+<br class="">
   // Consume the argument.<br class="">
   unsigned argIndex = FS.getArgIndex();<br class="">
   if (argIndex < NumDataArgs) {<br class="">
@@ -4003,7 +4009,7 @@ bool CheckScanfHandler::HandleScanfSpeci<br class="">
       // function if we encounter some other error.<br class="">
     CoveredArgs.set(argIndex);<br class="">
   }<br class="">
-<br class="">
+<br class="">
   // Check the length modifier is valid with the given conversion specifier.<br class="">
   if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo()))<br class="">
     HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,<br class="">
@@ -4020,21 +4026,28 @@ bool CheckScanfHandler::HandleScanfSpeci<br class="">
   // The remaining checks depend on the data arguments.<br class="">
   if (HasVAListArg)<br class="">
     return true;<br class="">
-<br class="">
+<br class="">
   if (!CheckNumArgs(FS, CS, startSpecifier, specifierLen, argIndex))<br class="">
     return false;<br class="">
-<br class="">
+<br class="">
   // Check that the argument type matches the format specifier.<br class="">
   const Expr *Ex = getDataArg(argIndex);<br class="">
   if (!Ex)<br class="">
     return true;<br class="">
<br class="">
   const analyze_format_string::ArgType &AT = FS.getArgType(S.Context);<br class="">
-  if (AT.isValid() && !AT.matchesType(S.Context, Ex->getType())) {<br class="">
+  analyze_format_string::ArgType::MatchKind match =<br class="">
+      AT.matchesType(S.Context, Ex->getType());<br class="">
+  if (AT.isValid() && match != analyze_format_string::ArgType::Match) {<br class="">
     ScanfSpecifier fixedFS = FS;<br class="">
-    bool success = fixedFS.fixType(Ex->getType(),<br class="">
-                                   Ex->IgnoreImpCasts()->getType(),<br class="">
-                                   S.getLangOpts(), S.Context);<br class="">
+    bool success =<br class="">
+        fixedFS.fixType(Ex->getType(), Ex->IgnoreImpCasts()->getType(),<br class="">
+                        S.getLangOpts(), S.Context);<br class="">
+<br class="">
+    unsigned diag = diag::warn_format_conversion_argument_type_mismatch;<br class="">
+    if (match == analyze_format_string::ArgType::NoMatchPedantic) {<br class="">
+      diag = diag::warn_format_conversion_argument_type_mismatch_pedantic;<br class="">
+    }<br class="">
<br class="">
     if (success) {<br class="">
       // Get the fix string from the fixed format specifier.<br class="">
@@ -4043,23 +4056,20 @@ bool CheckScanfHandler::HandleScanfSpeci<br class="">
       fixedFS.toString(os);<br class="">
<br class="">
       EmitFormatDiagnostic(<br class="">
-        S.PDiag(diag::warn_format_conversion_argument_type_mismatch)<br class="">
-          << AT.getRepresentativeTypeName(S.Context) << Ex->getType() << false<br class="">
-          << Ex->getSourceRange(),<br class="">
-        Ex->getLocStart(),<br class="">
-        /*IsStringLocation*/false,<br class="">
-        getSpecifierRange(startSpecifier, specifierLen),<br class="">
-        FixItHint::CreateReplacement(<br class="">
+          S.PDiag(diag) << AT.getRepresentativeTypeName(S.Context)<br class="">
+                        << Ex->getType() << false << Ex->getSourceRange(),<br class="">
+          Ex->getLocStart(),<br class="">
+          /*IsStringLocation*/ false,<br class="">
           getSpecifierRange(startSpecifier, specifierLen),<br class="">
-          os.str()));<br class="">
+          FixItHint::CreateReplacement(<br class="">
+              getSpecifierRange(startSpecifier, specifierLen), os.str()));<br class="">
     } else {<br class="">
       EmitFormatDiagnostic(<br class="">
-        S.PDiag(diag::warn_format_conversion_argument_type_mismatch)<br class="">
-          << AT.getRepresentativeTypeName(S.Context) << Ex->getType() << false<br class="">
-          << Ex->getSourceRange(),<br class="">
-        Ex->getLocStart(),<br class="">
-        /*IsStringLocation*/false,<br class="">
-        getSpecifierRange(startSpecifier, specifierLen));<br class="">
+          S.PDiag(diag) << AT.getRepresentativeTypeName(S.Context)<br class="">
+                        << Ex->getType() << false << Ex->getSourceRange(),<br class="">
+          Ex->getLocStart(),<br class="">
+          /*IsStringLocation*/ false,<br class="">
+          getSpecifierRange(startSpecifier, specifierLen));<br class="">
     }<br class="">
   }<br class="">
<br class="">
<br class="">
Modified: cfe/trunk/test/SemaCXX/format-strings-0x.cpp<br class="">
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/format-strings-0x.cpp?rev=231211&r1=231210&r2=231211&view=diff" target="_blank" class="">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/format-strings-0x.cpp?rev=231211&r1=231210&r2=231211&view=diff</a><br class="">
==============================================================================<br class="">
--- cfe/trunk/test/SemaCXX/format-strings-0x.cpp (original)<br class="">
+++ cfe/trunk/test/SemaCXX/format-strings-0x.cpp Tue Mar  3 21:12:10 2015<br class="">
@@ -8,6 +8,9 @@ extern int printf(const char *restrict,<br class="">
 void f(char **sp, float *fp) {<br class="">
   scanf("%as", sp); // expected-warning{{format specifies type 'float *' but the argument has type 'char **'}}<br class="">
<br class="">
+  printf("%p", sp); // expected-warning{{format specifies type 'void *' but the argument has type 'char **'}}<br class="">
+  scanf("%p", sp);  // expected-warning{{format specifies type 'void **' but the argument has type 'char **'}}<br class="">
+<br class="">
   printf("%a", 1.0);<br class="">
   scanf("%afoobar", fp);<br class="">
   printf(nullptr);<br class="">
<br class="">
<br class="">
_______________________________________________<br class="">
cfe-commits mailing list<br class="">
<a href="mailto:cfe-commits@cs.uiuc.edu" class="">cfe-commits@cs.uiuc.edu</a><br class="">
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank" class="">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br class="">
</blockquote></div><br class=""></div>
</div></blockquote></div><br class=""></div></body></html>