diff --git a/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp --- a/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/NSErrorChecker.cpp @@ -144,14 +144,14 @@ class NSErrorDerefBug : public BugType { public: - NSErrorDerefBug(const CheckerBase *Checker) + NSErrorDerefBug(const CheckerNameRef Checker) : BugType(Checker, "NSError** null dereference", "Coding conventions (Apple)") {} }; class CFErrorDerefBug : public BugType { public: - CFErrorDerefBug(const CheckerBase *Checker) + CFErrorDerefBug(const CheckerNameRef Checker) : BugType(Checker, "CFErrorRef* null dereference", "Coding conventions (Apple)") {} }; @@ -166,9 +166,9 @@ mutable std::unique_ptr NSBT; mutable std::unique_ptr CFBT; public: - bool ShouldCheckNSError, ShouldCheckCFError; - NSOrCFErrorDerefChecker() : NSErrorII(nullptr), CFErrorII(nullptr), - ShouldCheckNSError(0), ShouldCheckCFError(0) { } + DefaultBool ShouldCheckNSError, ShouldCheckCFError; + CheckerNameRef NSErrorName, CFErrorName; + NSOrCFErrorDerefChecker() : NSErrorII(nullptr), CFErrorII(nullptr) {} void checkLocation(SVal loc, bool isLoad, const Stmt *S, CheckerContext &C) const; @@ -276,12 +276,12 @@ BugType *bug = nullptr; if (isNSError) { if (!NSBT) - NSBT.reset(new NSErrorDerefBug(this)); + NSBT.reset(new NSErrorDerefBug(NSErrorName)); bug = NSBT.get(); } else { if (!CFBT) - CFBT.reset(new CFErrorDerefBug(this)); + CFBT.reset(new CFErrorDerefBug(CFErrorName)); bug = CFBT.get(); } BR.emitReport( @@ -331,6 +331,7 @@ mgr.registerChecker(); NSOrCFErrorDerefChecker *checker = mgr.getChecker(); checker->ShouldCheckNSError = true; + checker->NSErrorName = mgr.getCurrentCheckerName(); } bool ento::shouldRegisterNSErrorChecker(const CheckerManager &mgr) { @@ -341,6 +342,7 @@ mgr.registerChecker(); NSOrCFErrorDerefChecker *checker = mgr.getChecker(); checker->ShouldCheckCFError = true; + checker->CFErrorName = mgr.getCurrentCheckerName(); } bool ento::shouldRegisterCFErrorChecker(const CheckerManager &mgr) { diff --git a/clang/test/Analysis/incorrect-checker-names.mm b/clang/test/Analysis/incorrect-checker-names.mm --- a/clang/test/Analysis/incorrect-checker-names.mm +++ b/clang/test/Analysis/incorrect-checker-names.mm @@ -106,9 +106,19 @@ void foo(CFErrorRef* error) { // expected-warning{{Function accepting CFErrorRef* should have a non-void return value to indicate whether or not an error occurred [osx.coreFoundation.CFError]}} // FIXME: This shouldn't be tied to a modeling checker. - *error = 0; // expected-warning {{Potential null dereference. According to coding standards documented in CoreFoundation/CFError.h the parameter may be null [osx.NSOrCFErrorDerefChecker]}} + *error = 0; // expected-warning {{Potential null dereference. According to coding standards documented in CoreFoundation/CFError.h the parameter may be null [osx.coreFoundation.CFError]}} } +@interface A +- (void)myMethodWhichMayFail:(NSError **)error; +@end + +@implementation A +- (void)myMethodWhichMayFail:(NSError **)error { // expected-warning {{Method accepting NSError** should have a non-void return value to indicate whether or not an error occurred [osx.cocoa.NSError]}} + *error = [NSError errorWithDomain:@"domain" code:1 userInfo:0]; // expected-warning {{Potential null dereference. According to coding standards in 'Creating and Returning NSError Objects' the parameter may be null [osx.cocoa.NSError]}} +} +@end + bool write_into_out_param_on_success(OS_RETURNS_RETAINED OSObject **obj); void use_out_param_leak() {