From: Fariborz Jahanian Date: Mon, 18 May 2009 21:05:18 +0000 (+0000) Subject: more printf attribute on block declaration and X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=725165f2846bd37d3aaf863747fa30126992085e;p=clang more printf attribute on block declaration and checking when block is envoked. In progress. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@72039 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Sema/Sema.h b/lib/Sema/Sema.h index 9b953a8002..9df087ae68 100644 --- a/lib/Sema/Sema.h +++ b/lib/Sema/Sema.h @@ -2700,6 +2700,8 @@ public: private: Action::OwningExprResult CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall); + + Action::OwningExprResult CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall); SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, unsigned ByteNo) const; bool CheckObjCString(Expr *Arg); diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 22dcc49b55..a76463fac8 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -181,6 +181,34 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) { return move(TheCallResult); } +Action::OwningExprResult +Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall) { + + OwningExprResult TheCallResult(Owned(TheCall)); + // Printf checking. + const FormatAttr *Format = NDecl->getAttr(); + if (!Format) + return move(TheCallResult); + const VarDecl *V = dyn_cast(NDecl); + if (!V) + return move(TheCallResult); + QualType Ty = V->getType(); + if (!Ty->isBlockPointerType()) + return move(TheCallResult); + if (Format->getType() == "printf") { + bool HasVAListArg = Format->getFirstArg() == 0; + if (!HasVAListArg) { + const FunctionType *FT = + Ty->getAsBlockPointerType()->getPointeeType()->getAsFunctionType(); + if (const FunctionProtoType *Proto = dyn_cast(FT)) + HasVAListArg = !Proto->isVariadic(); + } + CheckPrintfArguments(TheCall, HasVAListArg, Format->getFormatIdx() - 1, + HasVAListArg ? 0 : Format->getFirstArg() - 1); + } + return move(TheCallResult); +} + /// SemaBuiltinAtomicOverloaded - We have a call to a function like /// __sync_fetch_and_add, which is an overloaded function based on the pointer /// type of its first argument. The main ActOnCallExpr routines have already diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index e5ee363825..0caad654ee 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -2692,6 +2692,8 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, // Do special checking on direct calls to functions. if (FDecl) return CheckFunctionCall(FDecl, TheCall.take()); + if (NDecl) + return CheckBlockCall(NDecl, TheCall.take()); return Owned(TheCall.take()); }