Index: clang/lib/Sema/SemaChecking.cpp
--- clang/lib/Sema/SemaChecking.cpp.orig
+++ clang/lib/Sema/SemaChecking.cpp
@@ -9872,7 +9872,7 @@ static const Expr *maybeConstEvalStringLiteral(ASTCont
 Sema::FormatStringType Sema::GetFormatStringType(const FormatAttr *Format) {
   return llvm::StringSwitch<FormatStringType>(Format->getType()->getName())
       .Case("scanf", FST_Scanf)
-      .Cases("printf", "printf0", FST_Printf)
+      .Cases("printf", "printf0", "syslog", FST_Printf)
       .Cases("NSString", "CFString", FST_NSString)
       .Case("strftime", FST_Strftime)
       .Case("strfmon", FST_Strfmon)
@@ -9969,6 +9969,7 @@ bool Sema::CheckFormatArguments(ArrayRef<const Expr *>
     case FST_Kprintf:
     case FST_FreeBSDKPrintf:
     case FST_Printf:
+    case FST_Syslog:
       Diag(FormatLoc, diag::note_format_security_fixit)
         << FixItHint::CreateInsertion(FormatLoc, "\"%s\", ");
       break;
@@ -10792,19 +10793,34 @@ bool CheckPrintfHandler::HandlePrintfSpecifier(
     // Claim the second argument.
     CoveredArgs.set(argIndex + 1);
 
-    // Type check the first argument (int for %b, pointer for %D)
     const Expr *Ex = getDataArg(argIndex);
-    const analyze_printf::ArgType &AT =
-      (CS.getKind() == ConversionSpecifier::FreeBSDbArg) ?
-        ArgType(S.Context.IntTy) : ArgType::CPointerTy;
-    if (AT.isValid() && !AT.matchesType(S.Context, Ex->getType()))
-      EmitFormatDiagnostic(
+    if (CS.getKind() == ConversionSpecifier::FreeBSDDArg) {
+      // Type check the first argument (pointer for %D)
+      const analyze_printf::ArgType &AT = ArgType::CPointerTy;
+      if (AT.isValid() && !AT.matchesType(S.Context, Ex->getType()))
+        EmitFormatDiagnostic(
           S.PDiag(diag::warn_format_conversion_argument_type_mismatch)
-              << AT.getRepresentativeTypeName(S.Context) << Ex->getType()
-              << false << Ex->getSourceRange(),
-          Ex->getBeginLoc(), /*IsStringLocation*/ false,
+          << AT.getRepresentativeTypeName(S.Context) << Ex->getType()
+          << false << Ex->getSourceRange(),
+          Ex->getBeginLoc(), /*IsStringLocation*/false,
           getSpecifierRange(startSpecifier, specifierLen));
+    } else {
+      // Check the length modifier for %b
+      if (!FS.hasValidLengthModifier(S.getASTContext().getTargetInfo(),
+                                     S.getLangOpts()))
+        HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
+                                    diag::warn_format_nonsensical_length);
+      else if (!FS.hasStandardLengthModifier())
+        HandleNonStandardLengthModifier(FS, startSpecifier, specifierLen);
+      else if (!FS.hasStandardLengthConversionCombination())
+        HandleInvalidLengthModifier(FS, CS, startSpecifier, specifierLen,
+                                    diag::warn_format_non_standard_conversion_spec);
 
+      // Type check the first argument of %b
+      if (!checkFormatExpr(FS, startSpecifier, specifierLen, Ex))
+        return false;
+    }
+
     // Type check the second argument (char * for both %b and %D)
     Ex = getDataArg(argIndex + 1);
     const analyze_printf::ArgType &AT2 = ArgType::CStrTy;
@@ -10842,6 +10858,15 @@ bool CheckPrintfHandler::HandlePrintfSpecifier(
     return true;
   }
 
+  // %n is not allowed anywhere
+  if (CS.getKind() == ConversionSpecifier::nArg) {
+    EmitFormatDiagnostic(S.PDiag(diag::warn_format_narg),
+                         getLocationOfByte(CS.getStart()),
+                         /*IsStringLocation*/ false,
+                         getSpecifierRange(startSpecifier, specifierLen));
+    return true;
+  }
+
   // Only scalars are allowed for os_trace.
   if (FSType == Sema::FST_OSTrace &&
       (CS.getKind() == ConversionSpecifier::PArg ||
@@ -11659,8 +11684,9 @@ static void CheckFormatString(
   }
 
   if (Type == Sema::FST_Printf || Type == Sema::FST_NSString ||
-      Type == Sema::FST_FreeBSDKPrintf || Type == Sema::FST_OSLog ||
-      Type == Sema::FST_OSTrace) {
+      Type == Sema::FST_Kprintf || Type == Sema::FST_FreeBSDKPrintf ||
+      Type == Sema::FST_OSLog || Type == Sema::FST_OSTrace ||
+      Type == Sema::FST_Syslog) {
     CheckPrintfHandler H(
         S, FExpr, OrigFormatExpr, Type, firstDataArg, numDataArgs,
         (Type == Sema::FST_NSString || Type == Sema::FST_OSTrace), Str, APK,
@@ -11669,7 +11695,7 @@ static void CheckFormatString(
 
     if (!analyze_format_string::ParsePrintfString(
             H, Str, Str + StrLen, S.getLangOpts(), S.Context.getTargetInfo(),
-            Type == Sema::FST_FreeBSDKPrintf))
+            Type == Sema::FST_Kprintf || Type == Sema::FST_FreeBSDKPrintf))
       H.DoneProcessing();
   } else if (Type == Sema::FST_Scanf) {
     CheckScanfHandler H(S, FExpr, OrigFormatExpr, Type, firstDataArg,
