We implement __attribute__((nonnull)), but only test for it on CallExpr
nodes. When calling a constructor, the AST only has a CXXConstructorExpr
with no CallExpr, so the warning doesn't fire. This patch adds the same test
that CallExpr uses to CXXConstructorExpr.
Please review!
Nick
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h (revision 128223)
+++ include/clang/Sema/Sema.h (working copy)
@@ -5300,7 +5300,8 @@
bool isPrintf);
void CheckNonNullArguments(const NonNullAttr *NonNull,
- const CallExpr *TheCall);
+ const Expr * const *ExprArgs,
+ SourceLocation CallSiteLoc);
void CheckPrintfScanfArguments(const CallExpr *TheCall, bool HasVAListArg,
unsigned format_idx, unsigned firstDataArg,
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp (revision 128223)
+++ lib/Sema/SemaDeclCXX.cpp (working copy)
@@ -6063,6 +6063,13 @@
unsigned NumExprs = ExprArgs.size();
Expr **Exprs = (Expr **)ExprArgs.release();
+ for (specific_attr_iterator<NonNullAttr>
+ i = Constructor->specific_attr_begin<NonNullAttr>(),
+ e = Constructor->specific_attr_end<NonNullAttr>(); i != e; ++i) {
+ const NonNullAttr *NonNull = *i;
+ CheckNonNullArguments(NonNull, ExprArgs.get(), ConstructLoc);
+ }
+
MarkDeclarationReferenced(ConstructLoc, Constructor);
return Owned(CXXConstructExpr::Create(Context, DeclInitType, ConstructLoc,
Constructor, Elidable, Exprs, NumExprs,
Index: lib/Sema/SemaChecking.cpp
===================================================================
--- lib/Sema/SemaChecking.cpp (revision 128223)
+++ lib/Sema/SemaChecking.cpp (working copy)
@@ -313,7 +313,8 @@
for (specific_attr_iterator<NonNullAttr>
i = FDecl->specific_attr_begin<NonNullAttr>(),
e = FDecl->specific_attr_end<NonNullAttr>(); i != e; ++i) {
- CheckNonNullArguments(*i, TheCall);
+ CheckNonNullArguments(*i, TheCall->getArgs(),
+ TheCall->getCallee()->getLocStart());
}
return false;
@@ -1030,15 +1031,15 @@
void
Sema::CheckNonNullArguments(const NonNullAttr *NonNull,
- const CallExpr *TheCall) {
+ const Expr * const *ExprArgs,
+ SourceLocation CallSiteLoc) {
for (NonNullAttr::args_iterator i = NonNull->args_begin(),
e = NonNull->args_end();
i != e; ++i) {
- const Expr *ArgExpr = TheCall->getArg(*i);
+ const Expr *ArgExpr = ExprArgs[*i];
if (ArgExpr->isNullPointerConstant(Context,
Expr::NPC_ValueDependentIsNotNull))
- Diag(TheCall->getCallee()->getLocStart(), diag::warn_null_arg)
- << ArgExpr->getSourceRange();
+ Diag(CallSiteLoc, diag::warn_null_arg) << ArgExpr->getSourceRange();
}
}
Index: test/SemaCXX/attr-nonnull.cpp
===================================================================
--- test/SemaCXX/attr-nonnull.cpp (revision 128223)
+++ test/SemaCXX/attr-nonnull.cpp (working copy)
@@ -1,5 +1,7 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s
struct S {
+ S(const char *) __attribute__((nonnull(2)));
+
static void f(const char*, const char*) __attribute__((nonnull(1)));
// GCC has a hidden 'this' argument in member functions, so the middle
@@ -10,7 +12,9 @@
expected-error{{invalid for the implicit this argument}}
};
-void test(S s) {
+void test() {
+ S s(0); // expected-warning{{null passed}}
+
s.f(0, ""); // expected-warning{{null passed}}
s.f("", 0);
s.g("", 0, ""); // expected-warning{{null passed}}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits