diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2009-05-14 18:00:00 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2009-05-14 18:00:00 +0000 |
commit | 4a528035fd7956515ac26149fe5d6ea41aed2fc0 (patch) | |
tree | d920af07ccb75a399efc9feb5632a57f7eefd3b2 /clang/lib | |
parent | 2daacd1f080156eb6678f083f05d2118ed8c2f7c (diff) | |
download | bcm5719-llvm-4a528035fd7956515ac26149fe5d6ea41aed2fc0.tar.gz bcm5719-llvm-4a528035fd7956515ac26149fe5d6ea41aed2fc0.zip |
Diagnose missing sentinel argument on a funciton call
with sentinel attribute.
llvm-svn: 71778
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/Sema/SemaExpr.cpp | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index a1c170cf284..6a7bca0165a 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -98,24 +98,44 @@ void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, const SentinelAttr *attr = D->getAttr<SentinelAttr>(); if (!attr) return; - ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D); - // FIXME: function calls for later. - if (!MD) - return; int sentinelPos = attr->getSentinel(); int nullPos = attr->getNullPos(); - // skip over named parameters. - ObjCMethodDecl::param_iterator P, E = MD->param_end(); + + // FIXME. ObjCMethodDecl and FunctionDecl need be derived from the + // same common base class. Then we won't be needing two versions of + // the same code. unsigned int i = 0; - for (P = MD->param_begin(); (P != E && i < NumArgs); ++P) { - if (nullPos) - --nullPos; - else - ++i; + bool warnNotEnoughArgs = false; + int isMethod = 0; + if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) { + // skip over named parameters. + ObjCMethodDecl::param_iterator P, E = MD->param_end(); + for (P = MD->param_begin(); (P != E && i < NumArgs); ++P) { + if (nullPos) + --nullPos; + else + ++i; + } + warnNotEnoughArgs = (P != E || i >= NumArgs); + isMethod = 1; + } + else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { + // skip over named parameters. + ObjCMethodDecl::param_iterator P, E = FD->param_end(); + for (P = FD->param_begin(); (P != E && i < NumArgs); ++P) { + if (nullPos) + --nullPos; + else + ++i; + } + warnNotEnoughArgs = (P != E || i >= NumArgs); } - if (P != E || i >= NumArgs) { + else + return; + + if (warnNotEnoughArgs) { Diag(Loc, diag::warn_not_enough_argument) << D->getDeclName(); - Diag(D->getLocation(), diag::note_sentinel_here); + Diag(D->getLocation(), diag::note_sentinel_here) << isMethod; return; } int sentinel = i; @@ -125,7 +145,7 @@ void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, } if (sentinelPos > 0) { Diag(Loc, diag::warn_not_enough_argument) << D->getDeclName(); - Diag(D->getLocation(), diag::note_sentinel_here); + Diag(D->getLocation(), diag::note_sentinel_here) << isMethod; return; } while (i < NumArgs-1) { @@ -135,8 +155,8 @@ void Sema::DiagnoseSentinelCalls(NamedDecl *D, SourceLocation Loc, Expr *sentinelExpr = Args[sentinel]; if (sentinelExpr && (!sentinelExpr->getType()->isPointerType() || !sentinelExpr->isNullPointerConstant(Context))) { - Diag(Loc, diag::warn_missing_sentinel); - Diag(D->getLocation(), diag::note_sentinel_here); + Diag(Loc, diag::warn_missing_sentinel) << isMethod << isMethod; + Diag(D->getLocation(), diag::note_sentinel_here) << isMethod; } return; } @@ -2619,8 +2639,10 @@ Sema::ActOnCallExpr(Scope *S, ExprArg fn, SourceLocation LParenLoc, << Fn->getSourceRange()); // Do special checking on direct calls to functions. - if (FDecl) + if (FDecl) { + DiagnoseSentinelCalls(FDecl, LParenLoc, Args, NumArgs); return CheckFunctionCall(FDecl, TheCall.take()); + } return Owned(TheCall.take()); } |