more printf attribute on block declaration and

checking when block is envoked. In progress.

llvm-svn: 72039
This commit is contained in:
Fariborz Jahanian 2009-05-18 21:05:18 +00:00
parent d9145fca7f
commit c1585be6bd
3 changed files with 32 additions and 0 deletions

View File

@ -2700,6 +2700,8 @@ public:
private: private:
Action::OwningExprResult CheckFunctionCall(FunctionDecl *FDecl, Action::OwningExprResult CheckFunctionCall(FunctionDecl *FDecl,
CallExpr *TheCall); CallExpr *TheCall);
Action::OwningExprResult CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall);
SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL, SourceLocation getLocationOfStringLiteralByte(const StringLiteral *SL,
unsigned ByteNo) const; unsigned ByteNo) const;
bool CheckObjCString(Expr *Arg); bool CheckObjCString(Expr *Arg);

View File

@ -181,6 +181,34 @@ Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
return move(TheCallResult); return move(TheCallResult);
} }
Action::OwningExprResult
Sema::CheckBlockCall(NamedDecl *NDecl, CallExpr *TheCall) {
OwningExprResult TheCallResult(Owned(TheCall));
// Printf checking.
const FormatAttr *Format = NDecl->getAttr<FormatAttr>();
if (!Format)
return move(TheCallResult);
const VarDecl *V = dyn_cast<VarDecl>(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<FunctionProtoType>(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 /// SemaBuiltinAtomicOverloaded - We have a call to a function like
/// __sync_fetch_and_add, which is an overloaded function based on the pointer /// __sync_fetch_and_add, which is an overloaded function based on the pointer
/// type of its first argument. The main ActOnCallExpr routines have already /// type of its first argument. The main ActOnCallExpr routines have already

View File

@ -2692,6 +2692,8 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc,
// Do special checking on direct calls to functions. // Do special checking on direct calls to functions.
if (FDecl) if (FDecl)
return CheckFunctionCall(FDecl, TheCall.take()); return CheckFunctionCall(FDecl, TheCall.take());
if (NDecl)
return CheckBlockCall(NDecl, TheCall.take());
return Owned(TheCall.take()); return Owned(TheCall.take());
} }