Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h	(revision 236098)
+++ include/clang/Sema/Sema.h	(working copy)
@@ -7781,9 +7781,9 @@
     VariadicDoesNotApply
   };
 
-  VariadicCallType getVariadicCallType(FunctionDecl *FDecl,
+  VariadicCallType getVariadicCallType(const Decl *FDecl,
                                        const FunctionProtoType *Proto,
-                                       Expr *Fn);
+                                       const Expr *Fn);
 
   // Used for determining in which context a type is allowed to be passed to a
   // vararg function.
@@ -8456,12 +8456,12 @@
   bool CheckPointerCall(NamedDecl *NDecl, CallExpr *TheCall,
                         const FunctionProtoType *Proto);
   bool CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto);
-  void CheckConstructorCall(FunctionDecl *FDecl,
-                            ArrayRef<const Expr *> Args,
-                            const FunctionProtoType *Proto,
-                            SourceLocation Loc);
+  bool CheckBlockCall(const BlockDecl *BDecl, CallExpr *TheCall,
+                      const FunctionProtoType *Proto);
+  void CheckConstructorCall(FunctionDecl *FDecl, ArrayRef<const Expr *> Args,
+                            const FunctionProtoType *Proto, SourceLocation Loc);
 
-  void checkCall(NamedDecl *FDecl, ArrayRef<const Expr *> Args,
+  void checkCall(const Decl *FDecl, ArrayRef<const Expr *> Args,
                  unsigned NumParams, bool IsMemberFunction, SourceLocation Loc,
                  SourceRange Range, VariadicCallType CallType);
 
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp	(revision 236098)
+++ lib/Sema/SemaChecking.cpp	(working copy)
@@ -1126,7 +1126,7 @@
 }
 
 static void CheckNonNullArguments(Sema &S,
-                                  const NamedDecl *FDecl,
+                                  const Decl *FDecl,
                                   ArrayRef<const Expr *> Args,
                                   SourceLocation CallSiteLoc) {
   // Check the attributes attached to the method/function itself.
@@ -1151,10 +1151,12 @@
 
   // Check the attributes on the parameters.
   ArrayRef<ParmVarDecl*> parms;
-  if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(FDecl))
+  if (const auto *FD = dyn_cast<FunctionDecl>(FDecl))
     parms = FD->parameters();
-  else if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(FDecl))
+  else if (const auto *MD = dyn_cast<ObjCMethodDecl>(FDecl))
     parms = MD->parameters();
+  else if (const auto *BD = dyn_cast<BlockDecl>(FDecl))
+    parms = BD->parameters();
 
   unsigned ArgIndex = 0;
   for (ArrayRef<ParmVarDecl*>::iterator I = parms.begin(), E = parms.end();
@@ -1173,7 +1175,7 @@
 
 /// Handles the checks for format strings, non-POD arguments to vararg
 /// functions, and NULL arguments passed to non-NULL parameters.
-void Sema::checkCall(NamedDecl *FDecl, ArrayRef<const Expr *> Args,
+void Sema::checkCall(const Decl *FDecl, ArrayRef<const Expr *> Args,
                      unsigned NumParams, bool IsMemberFunction,
                      SourceLocation Loc, SourceRange Range,
                      VariadicCallType CallType) {
@@ -1318,6 +1320,19 @@
   return false;
 }
 
+bool Sema::CheckBlockCall(const BlockDecl *BDecl, CallExpr *TheCall,
+                          const FunctionProtoType *Proto) {
+  VariadicCallType CallType =
+      getVariadicCallType(BDecl, Proto, TheCall->getCallee());
+  unsigned NumParams = Proto ? Proto->getNumParams() : 0;
+
+  checkCall(BDecl,
+            llvm::makeArrayRef(TheCall->getArgs(), TheCall->getNumArgs()),
+            NumParams, /*IsMemberFunction=*/false, TheCall->getRParenLoc(),
+            TheCall->getCallee()->getSourceRange(), CallType);
+  return false;
+}
+
 /// Checks function calls when a FunctionDecl or a NamedDecl is not available,
 /// such as function pointers returned from functions.
 bool Sema::CheckOtherCall(CallExpr *TheCall, const FunctionProtoType *Proto) {
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp	(revision 236098)
+++ lib/Sema/SemaExpr.cpp	(working copy)
@@ -4183,15 +4183,16 @@
 
 
 Sema::VariadicCallType
-Sema::getVariadicCallType(FunctionDecl *FDecl, const FunctionProtoType *Proto,
-                          Expr *Fn) {
+Sema::getVariadicCallType(const Decl *FDecl, const FunctionProtoType *Proto,
+                          const Expr *Fn) {
   if (Proto && Proto->isVariadic()) {
     if (dyn_cast_or_null<CXXConstructorDecl>(FDecl))
       return VariadicConstructor;
-    else if (Fn && Fn->getType()->isBlockPointerType())
+    else if (dyn_cast_or_null<BlockDecl>(FDecl) ||
+             (Fn && Fn->getType()->isBlockPointerType()))
       return VariadicBlock;
     else if (FDecl) {
-      if (CXXMethodDecl *Method = dyn_cast_or_null<CXXMethodDecl>(FDecl))
+      if (const auto *Method = dyn_cast_or_null<CXXMethodDecl>(FDecl))
         if (Method->isInstance())
           return VariadicMethod;
     } else if (Fn && Fn->getType() == Context.BoundMemberTy)
@@ -5036,6 +5037,9 @@
   } else if (NDecl) {
     if (CheckPointerCall(NDecl, TheCall, Proto))
       return ExprError();
+  } else if (const auto *BE = dyn_cast<BlockExpr>(Fn)) {
+    if (CheckBlockCall(BE->getBlockDecl(), TheCall, Proto))
+      return ExprError();
   } else {
     if (CheckOtherCall(TheCall, Proto))
       return ExprError();
Index: test/SemaObjC/nonnull.m
===================================================================
--- test/SemaObjC/nonnull.m	(revision 236098)
+++ test/SemaObjC/nonnull.m	(working copy)
@@ -125,3 +125,7 @@
 }
 
 void (^PR23117)(int *) = ^(int *p1) __attribute__((nonnull(1))) {};
+
+void PR23146() {
+    ^(int *p1) __attribute__((nonnull(1))) {}(0); // expected-warning {{null passed to a callee that requires a non-null argument}}
+}
