Alternate format string checking: issue a warning for invalid conversion specifiers.


git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94792 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 3cd45a2..a6d5097 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -1306,7 +1306,16 @@
       TheCall(theCall), FormatIdx(formatIdx) {}
   
   void DoneProcessing();
-    
+   
+//  void HandleIncompleteFormatSpecifier(const char *startSpecifier,
+//                                       const char *endSpecifier);
+  
+//  void HandleIncompletePrecision(const char *periodChar);
+  
+  void HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
+                                        const char *startSpecifier,
+                                        unsigned specifierLen);
+  
   void HandleNullChar(const char *nullCharacter);
   
   bool HandleFormatSpecifier(const analyze_printf::FormatSpecifier &FS,
@@ -1331,6 +1340,20 @@
   return S.getLocationOfStringLiteralByte(FExpr, x - Beg);  
 }
 
+void CheckPrintfHandler::
+HandleInvalidConversionSpecifier(const analyze_printf::FormatSpecifier &FS,
+                                 const char *startSpecifier,
+                                 unsigned specifierLen) {
+  
+  ++NumConversions;
+  
+  SourceLocation Loc =
+    getLocationOfByte(FS.getConversionSpecifier().getStart());
+  S.Diag(Loc, diag::warn_printf_invalid_conversion)
+      << llvm::StringRef(startSpecifier, specifierLen)
+      << getFormatRange();  
+}
+
 void CheckPrintfHandler::HandleNullChar(const char *nullCharacter) {
   // The presence of a null character is likely an error.
   S.Diag(getLocationOfByte(nullCharacter),
@@ -1373,7 +1396,6 @@
   }
   return true;
 }
-                                      
 
 bool
 CheckPrintfHandler::HandleFormatSpecifier(const analyze_printf::FormatSpecifier &FS,
@@ -1397,20 +1419,17 @@
     return false;
   }
 
-  ++NumConversions;  
-  
   // Check for using an Objective-C specific conversion specifier
   // in a non-ObjC literal.
   if (!IsObjCLiteral && CS.isObjCArg()) {
-    SourceLocation Loc = getLocationOfByte(CS.getStart());
-    S.Diag(Loc, diag::warn_printf_invalid_conversion)
-      << llvm::StringRef(startSpecifier, specifierLen)
-      << getFormatRange();
+    HandleInvalidConversionSpecifier(FS, startSpecifier, specifierLen);
     
     // Continue checking the other format specifiers.
     return true;
   }
   
+  ++NumConversions;  
+  
   // Are we using '%n'?  Issue a warning about this being
   // a possible security issue.
   if (CS.getKind() == ConversionSpecifier::OutIntPtrArg) {