summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorFariborz Jahanian <fjahanian@apple.com>2009-05-14 18:00:00 +0000
committerFariborz Jahanian <fjahanian@apple.com>2009-05-14 18:00:00 +0000
commit4a528035fd7956515ac26149fe5d6ea41aed2fc0 (patch)
treed920af07ccb75a399efc9feb5632a57f7eefd3b2 /clang/lib
parent2daacd1f080156eb6678f083f05d2118ed8c2f7c (diff)
downloadbcm5719-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.cpp56
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());
}
OpenPOWER on IntegriCloud