Author: nicholas Date: Wed Jun 15 00:18:39 2016 New Revision: 272755 URL: http://llvm.org/viewvc/llvm-project?rev=272755&view=rev Log: Add a "declared 'nonnull' here" note to warnings where an expression is checked against null.
Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td cfe/trunk/lib/Sema/SemaChecking.cpp cfe/trunk/test/Sema/nonnull.c Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=272755&r1=272754&r2=272755&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original) +++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Wed Jun 15 00:18:39 2016 @@ -2933,6 +2933,8 @@ def warn_attribute_nonnull_no_pointers : 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>; Modified: cfe/trunk/lib/Sema/SemaChecking.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaChecking.cpp?rev=272755&r1=272754&r2=272755&view=diff ============================================================================== --- cfe/trunk/lib/Sema/SemaChecking.cpp (original) +++ cfe/trunk/lib/Sema/SemaChecking.cpp Wed Jun 15 00:18:39 2016 @@ -8460,7 +8460,8 @@ void Sema::DiagnoseAlwaysNonNullPointer( } } - 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( : 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( 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( 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; } } Modified: cfe/trunk/test/Sema/nonnull.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Sema/nonnull.c?rev=272755&r1=272754&r2=272755&view=diff ============================================================================== --- cfe/trunk/test/Sema/nonnull.c (original) +++ cfe/trunk/test/Sema/nonnull.c Wed Jun 15 00:18:39 2016 @@ -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 } 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* } } -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)) ; } -__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}} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits