From 909a70d8a185f701c20bacc3c76f8f5979cbbc7c Mon Sep 17 00:00:00 2001 From: Nick Lewycky Date: Fri, 25 Mar 2011 01:44:32 +0000 Subject: [PATCH] Apply the nonnull attribute to constructor expressions too. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@128253 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Sema/Sema.h | 3 ++- lib/Sema/SemaChecking.cpp | 11 ++++++----- lib/Sema/SemaDeclCXX.cpp | 7 +++++++ test/SemaCXX/attr-nonnull.cpp | 6 +++++- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h index bacd7691a3..d661a040df 100644 --- a/include/clang/Sema/Sema.h +++ b/include/clang/Sema/Sema.h @@ -5300,7 +5300,8 @@ private: 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, diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index de5a796410..15644c99d9 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -313,7 +313,8 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) { for (specific_attr_iterator i = FDecl->specific_attr_begin(), e = FDecl->specific_attr_end(); i != e; ++i) { - CheckNonNullArguments(*i, TheCall); + CheckNonNullArguments(*i, TheCall->getArgs(), + TheCall->getCallee()->getLocStart()); } return false; @@ -1030,15 +1031,15 @@ bool Sema::SemaCheckStringLiteral(const Expr *E, const CallExpr *TheCall, 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(); } } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index edee86476b..db77d10421 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -6063,6 +6063,13 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, unsigned NumExprs = ExprArgs.size(); Expr **Exprs = (Expr **)ExprArgs.release(); + for (specific_attr_iterator + i = Constructor->specific_attr_begin(), + e = Constructor->specific_attr_end(); 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, diff --git a/test/SemaCXX/attr-nonnull.cpp b/test/SemaCXX/attr-nonnull.cpp index 19d6642eb5..09c054c197 100644 --- a/test/SemaCXX/attr-nonnull.cpp +++ b/test/SemaCXX/attr-nonnull.cpp @@ -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 @@ struct S { 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}} -- 2.40.0