[cfe-commits] r71778 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/SemaExpr.cpp test/Sema/function-sentinel-attr.c
Fariborz Jahanian
fjahanian at apple.com
Thu May 14 11:00:34 PDT 2009
Author: fjahanian
Date: Thu May 14 13:00:00 2009
New Revision: 71778
URL: http://llvm.org/viewvc/llvm-project?rev=71778&view=rev
Log:
Diagnose missing sentinel argument on a funciton call
with sentinel attribute.
Added:
cfe/trunk/test/Sema/function-sentinel-attr.c
Modified:
cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
cfe/trunk/lib/Sema/SemaExpr.cpp
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=71778&r1=71777&r2=71778&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Thu May 14 13:00:00 2009
@@ -780,9 +780,9 @@
def warn_not_enough_argument : Warning<
"not enough variable arguments in %0 declaration to fit a sentinel">;
def warn_missing_sentinel : Warning <
- "missing sentinel in method dispatch">;
+ "missing sentinel in %select{function|method}0 %select{call|dispatch}1">;
def note_sentinel_here : Note<
- "method has been explicitly marked sentinel here">;
+ "%select{function|method}0 has been explicitly marked sentinel here">;
def warn_missing_prototype : Warning<
"no previous prototype for function %0">,
InGroup<DiagGroup<"missing-prototypes">>, DefaultIgnore;
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=71778&r1=71777&r2=71778&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu May 14 13:00:00 2009
@@ -98,24 +98,44 @@
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 @@
}
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 @@
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 @@
<< 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());
}
Added: cfe/trunk/test/Sema/function-sentinel-attr.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/function-sentinel-attr.c?rev=71778&view=auto
==============================================================================
--- cfe/trunk/test/Sema/function-sentinel-attr.c (added)
+++ cfe/trunk/test/Sema/function-sentinel-attr.c Thu May 14 13:00:00 2009
@@ -0,0 +1,30 @@
+// RUN: clang-cc -fsyntax-only -verify %s
+
+#define NULL (void*)0
+
+#define ATTR __attribute__ ((__sentinel__))
+
+void foo1 (int x, ...) ATTR; // expected-note {{function has been explicitly marked sentinel here}}
+void foo5 (int x, ...) __attribute__ ((__sentinel__(1))); // expected-note {{function has been explicitly marked sentinel here}}
+void foo6 (int x, ...) __attribute__ ((__sentinel__(5))); // expected-note {{function has been explicitly marked sentinel here}}
+void foo7 (int x, ...) __attribute__ ((__sentinel__(0))); // expected-note {{function has been explicitly marked sentinel here}}
+void foo10 (int x, ...) __attribute__ ((__sentinel__(1,1)));
+void foo12 (int x, ... ) ATTR; // expected-note {{function has been explicitly marked sentinel here}}
+
+int main ()
+{
+
+ foo1(1, NULL); // OK
+ foo1(1, 0) ; // expected-warning {{missing sentinel in function call}}
+ foo5(1, NULL, 2); // OK
+ foo5(1,2,NULL, 1); // OK
+ foo5(1, NULL, 2, 1); // expected-warning {{missing sentinel in function call}}
+
+ foo6(1,2,3,4,5,6,7); // expected-warning {{missing sentinel in function call}}
+ foo6(1,NULL,3,4,5,6,7); // OK
+ foo7(1); // expected-warning {{not enough variable arguments in 'foo7' declaration to fit a sentinel}}
+ foo7(1, NULL); // OK
+
+ foo12(1); // expected-warning {{not enough variable arguments in 'foo12' declaration to fit a sentinel}}
+}
+
More information about the cfe-commits
mailing list