forked from OSchip/llvm-project
Add a "declared 'nonnull' here" note to warnings where an expression is checked against null.
llvm-svn: 272755
This commit is contained in:
parent
a65a237805
commit
bc85ec8656
|
@ -2933,6 +2933,8 @@ def warn_attribute_nonnull_no_pointers : Warning<
|
|||
def warn_attribute_nonnull_parm_no_args : Warning<
|
||||
"'nonnull' attribute when used on parameters takes no arguments">,
|
||||
InGroup<IgnoredAttributes>;
|
||||
def note_declared_nonnull : Note<
|
||||
"declared %select{'returns_nonnull'|'nonnull'}0 here">;
|
||||
def warn_attribute_sentinel_named_arguments : Warning<
|
||||
"'sentinel' attribute requires named arguments">,
|
||||
InGroup<IgnoredAttributes>;
|
||||
|
|
|
@ -8460,7 +8460,8 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
|
|||
}
|
||||
}
|
||||
|
||||
auto ComplainAboutNonnullParamOrCall = [&](bool IsParam) {
|
||||
auto ComplainAboutNonnullParamOrCall = [&](const Attr *NonnullAttr) {
|
||||
bool IsParam = isa<NonNullAttr>(NonnullAttr);
|
||||
std::string Str;
|
||||
llvm::raw_string_ostream S(Str);
|
||||
E->printPretty(S, nullptr, getPrintingPolicy());
|
||||
|
@ -8468,13 +8469,14 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
|
|||
: diag::warn_cast_nonnull_to_bool;
|
||||
Diag(E->getExprLoc(), DiagID) << IsParam << S.str()
|
||||
<< E->getSourceRange() << Range << IsEqual;
|
||||
Diag(NonnullAttr->getLocation(), diag::note_declared_nonnull) << IsParam;
|
||||
};
|
||||
|
||||
// If we have a CallExpr that is tagged with returns_nonnull, we can complain.
|
||||
if (auto *Call = dyn_cast<CallExpr>(E->IgnoreParenImpCasts())) {
|
||||
if (auto *Callee = Call->getDirectCallee()) {
|
||||
if (Callee->hasAttr<ReturnsNonNullAttr>()) {
|
||||
ComplainAboutNonnullParamOrCall(false);
|
||||
if (const Attr *A = Callee->getAttr<ReturnsNonNullAttr>()) {
|
||||
ComplainAboutNonnullParamOrCall(A);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -8496,8 +8498,8 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
|
|||
if (const auto* PV = dyn_cast<ParmVarDecl>(D)) {
|
||||
if (getCurFunction() &&
|
||||
!getCurFunction()->ModifiedNonNullParams.count(PV)) {
|
||||
if (PV->hasAttr<NonNullAttr>()) {
|
||||
ComplainAboutNonnullParamOrCall(true);
|
||||
if (const Attr *A = PV->getAttr<NonNullAttr>()) {
|
||||
ComplainAboutNonnullParamOrCall(A);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -8508,13 +8510,13 @@ void Sema::DiagnoseAlwaysNonNullPointer(Expr *E,
|
|||
|
||||
for (const auto *NonNull : FD->specific_attrs<NonNullAttr>()) {
|
||||
if (!NonNull->args_size()) {
|
||||
ComplainAboutNonnullParamOrCall(true);
|
||||
ComplainAboutNonnullParamOrCall(NonNull);
|
||||
return;
|
||||
}
|
||||
|
||||
for (unsigned ArgNo : NonNull->args()) {
|
||||
if (ArgNo == ParamNo) {
|
||||
ComplainAboutNonnullParamOrCall(true);
|
||||
ComplainAboutNonnullParamOrCall(NonNull);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,7 +86,7 @@ void redecl_test(void *p) {
|
|||
|
||||
// rdar://18712242
|
||||
#define NULL (void*)0
|
||||
__attribute__((__nonnull__))
|
||||
__attribute__((__nonnull__)) // expected-note 2{{declared 'nonnull' here}}
|
||||
int evil_nonnull_func(int* pointer, void * pv)
|
||||
{
|
||||
if (pointer == NULL) { // expected-warning {{comparison of nonnull parameter 'pointer' equal to a null pointer is 'false' on first encounter}}
|
||||
|
@ -105,7 +105,7 @@ int evil_nonnull_func(int* pointer, void * pv)
|
|||
}
|
||||
|
||||
void set_param_to_null(int**);
|
||||
int another_evil_nonnull_func(int* pointer, char ch, void * pv) __attribute__((nonnull(1, 3)));
|
||||
int another_evil_nonnull_func(int* pointer, char ch, void * pv) __attribute__((nonnull(1, 3))); // expected-note 2{{declared 'nonnull' here}}
|
||||
int another_evil_nonnull_func(int* pointer, char ch, void * pv) {
|
||||
if (pointer == NULL) { // expected-warning {{comparison of nonnull parameter 'pointer' equal to a null pointer is 'false' on first encounter}}
|
||||
return 0;
|
||||
|
@ -127,7 +127,7 @@ extern void FOO();
|
|||
extern void FEE();
|
||||
|
||||
extern void *pv;
|
||||
__attribute__((__nonnull__))
|
||||
__attribute__((__nonnull__)) // expected-note {{declared 'nonnull' here}}
|
||||
void yet_another_evil_nonnull_func(int* pointer)
|
||||
{
|
||||
while (pv) {
|
||||
|
@ -141,7 +141,7 @@ void yet_another_evil_nonnull_func(int* pointer)
|
|||
}
|
||||
}
|
||||
|
||||
void pr21668_1(__attribute__((nonnull)) const char *p, const char *s) {
|
||||
void pr21668_1(__attribute__((nonnull)) const char *p, const char *s) { // expected-note {{declared 'nonnull' here}}
|
||||
if (p) // expected-warning {{nonnull parameter 'p' will evaluate to 'true' on first encounter}}
|
||||
;
|
||||
if (s) // No warning
|
||||
|
@ -154,7 +154,7 @@ void pr21668_2(__attribute__((nonnull)) const char *p) {
|
|||
;
|
||||
}
|
||||
|
||||
__attribute__((returns_nonnull)) void *returns_nonnull_whee();
|
||||
__attribute__((returns_nonnull)) void *returns_nonnull_whee(); // expected-note 6{{declared 'returns_nonnull' here}}
|
||||
|
||||
void returns_nonnull_warning_tests() {
|
||||
if (returns_nonnull_whee() == NULL) {} // expected-warning {{comparison of nonnull function call 'returns_nonnull_whee()' equal to a null pointer is 'false' on first encounter}}
|
||||
|
|
Loading…
Reference in New Issue