зеркало из https://github.com/microsoft/clang-1.git
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
This commit is contained in:
Родитель
2a523eec6a
Коммит
909a70d8a1
|
@ -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,
|
||||
|
|
|
@ -313,7 +313,8 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall) {
|
|||
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 @@ 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6063,6 +6063,13 @@ Sema::BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType,
|
|||
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,
|
||||
|
|
|
@ -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}}
|
||||
|
|
Загрузка…
Ссылка в новой задаче