Support the 'a' length modifier in scanf format strings as a C90
extension.

This fixes gcc.dg/format/c90-scanf-3.c and ext-4.c (test for excess
errors).

llvm-svn: 146649
diff --git a/clang/lib/Analysis/PrintfFormatString.cpp b/clang/lib/Analysis/PrintfFormatString.cpp
index 45e3268..4e9a464 100644
--- a/clang/lib/Analysis/PrintfFormatString.cpp
+++ b/clang/lib/Analysis/PrintfFormatString.cpp
@@ -51,7 +51,8 @@
 static PrintfSpecifierResult ParsePrintfSpecifier(FormatStringHandler &H,
                                                   const char *&Beg,
                                                   const char *E,
-                                                  unsigned &argIndex) {
+                                                  unsigned &argIndex,
+                                                  const LangOptions &LO) {
 
   using namespace clang::analyze_format_string;
   using namespace clang::analyze_printf;
@@ -150,7 +151,7 @@
   }
 
   // Look for the length modifier.
-  if (ParseLengthModifier(FS, I, E) && I == E) {
+  if (ParseLengthModifier(FS, I, E, LO) && I == E) {
     // No more characters left?
     H.HandleIncompleteSpecifier(Start, E - Start);
     return true;
@@ -210,13 +211,15 @@
 
 bool clang::analyze_format_string::ParsePrintfString(FormatStringHandler &H,
                                                      const char *I,
-                                                     const char *E) {
+                                                     const char *E,
+                                                     const LangOptions &LO) {
 
   unsigned argIndex = 0;
 
   // Keep looking for a format specifier until we have exhausted the string.
   while (I != E) {
-    const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex);
+    const PrintfSpecifierResult &FSR = ParsePrintfSpecifier(H, I, E, argIndex,
+                                                            LO);
     // Did a fail-stop error of any kind occur when parsing the specifier?
     // If so, don't do any more processing.
     if (FSR.shouldStop())
@@ -269,6 +272,8 @@
         return ArgTypeResult();
       case LengthModifier::AsPtrDiff:
         return ArgTypeResult(Ctx.getPointerDiffType(), "ptrdiff_t");
+      case LengthModifier::AsAllocate:
+        return ArgTypeResult::Invalid();
     }
 
   if (CS.isUIntArg())
@@ -288,6 +293,8 @@
         // FIXME: How to get the corresponding unsigned
         // version of ptrdiff_t?
         return ArgTypeResult();
+      case LengthModifier::AsAllocate:
+        return ArgTypeResult::Invalid();
     }
 
   if (CS.isDoubleArg()) {