[PATCH] D22968: [analyzer] A checker for macOS-specific bool- and number-like objects.
This revision was automatically updated to reflect the committed changes. Closed by commit rL284473: [analyzer] Add NumberObjectConversion checker. (authored by dergachev). Changed prior to commit: https://reviews.llvm.org/D22968?vs=74969&id=74979#toc Repository: rL LLVM https://reviews.llvm.org/D22968 Files: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td cfe/trunk/lib/StaticAnalyzer/Checkers/CMakeLists.txt cfe/trunk/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp cfe/trunk/test/Analysis/Inputs/system-header-simulator-objc.h cfe/trunk/test/Analysis/number-object-conversion.cpp cfe/trunk/test/Analysis/number-object-conversion.m Index: cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td === --- cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td +++ cfe/trunk/include/clang/StaticAnalyzer/Checkers/Checkers.td @@ -474,6 +474,11 @@ let ParentPackage = OSX in { +def NumberObjectConversionChecker : Checker<"NumberObjectConversion">, + InPackage, + HelpText<"Check for erroneous conversions of objects representing numbers into numbers">, + DescFile<"NumberObjectConversionChecker.cpp">; + def MacOSXAPIChecker : Checker<"API">, InPackage, HelpText<"Check for proper uses of various Apple APIs">, Index: cfe/trunk/test/Analysis/Inputs/system-header-simulator-objc.h === --- cfe/trunk/test/Analysis/Inputs/system-header-simulator-objc.h +++ cfe/trunk/test/Analysis/Inputs/system-header-simulator-objc.h @@ -10,10 +10,16 @@ typedef signed long CFIndex; typedef signed char BOOL; +#define YES ((BOOL)1) +#define NO ((BOOL)0) + typedef unsigned long NSUInteger; typedef unsigned short unichar; typedef UInt16 UniChar; +#define NULL ((void *)0) +#define nil ((id)0) + enum { NSASCIIStringEncoding = 1, NSNEXTSTEPStringEncoding = 2, @@ -72,6 +78,7 @@ @end @interface NSNumber : NSValue - (char)charValue; - (id)initWithInt:(int)value; +- (BOOL)boolValue; @end @class NSString; @interface NSArray : NSObject - (NSUInteger)count; @end @interface NSArray (NSArrayCreation) + (id)array; Index: cfe/trunk/test/Analysis/number-object-conversion.cpp === --- cfe/trunk/test/Analysis/number-object-conversion.cpp +++ cfe/trunk/test/Analysis/number-object-conversion.cpp @@ -0,0 +1,65 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin10 -w -std=c++11 -analyze -analyzer-checker=osx.NumberObjectConversion %s -verify +// RUN: %clang_cc1 -triple i386-apple-darwin10 -w -std=c++11 -analyze -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify + +#define NULL ((void *)0) +#include "Inputs/system-header-simulator-cxx.h" // for nullptr + +class OSBoolean { +public: + virtual bool isTrue() const; + virtual bool isFalse() const; +}; + +extern const OSBoolean *const &kOSBooleanFalse; +extern const OSBoolean *const &kOSBooleanTrue; + +void takes_bool(bool); + +void bad(const OSBoolean *p) { +#ifdef PEDANTIC + if (p) {} // expected-warning{{Converting 'const class OSBoolean *' to a plain boolean value for branching; please compare the pointer to NULL or nullptr instead to suppress this warning}} + if (!p) {} // expected-warning{{Converting 'const class OSBoolean *' to a plain boolean value for branching; please compare the pointer to NULL or nullptr instead to suppress this warning}} + p ? 1 : 2; // expected-warning{{Converting 'const class OSBoolean *' to a plain boolean value for branching; please compare the pointer to NULL or nullptr instead to suppress this warning}} + (bool)p; // expected-warning{{Converting 'const class OSBoolean *' to a plain bool value; please compare the pointer to NULL or nullptr instead to suppress this warning}} +#endif + bool x = p; // expected-warning{{Converting 'const class OSBoolean *' to a plain bool value; pointer value is being used instead}} + x = p; // expected-warning{{Converting 'const class OSBoolean *' to a plain bool value; pointer value is being used instead}} + takes_bool(p); // expected-warning{{Converting 'const class OSBoolean *' to a plain bool value; pointer value is being used instead}} + takes_bool(x); // no-warning +} + +typedef bool sugared_bool; +typedef const OSBoolean *sugared_OSBoolean; +void bad_sugared(sugared_OSBoolean p) { + sugared_bool x = p; // expected-warning{{Converting 'const class OSBoolean *' to a plain bool value; pointer value is being used instead}} +} + +void good(const OSBoolean *p) { + bool x = p->isTrue(); // no-warning + (bool)p->isFalse(); // no-warning + if (p == kOSBooleanTrue) {} // no-warning +} + +void suppression(const OSBoolean *p) { + if (p == NULL) {} // no-warning + bool y = (p == nullptr); // no-warning +} + +// Conversion of a pointer to an intptr_t is fine. +typedef long intptr_t; +typedef un
[PATCH] D22968: [analyzer] A checker for macOS-specific bool- and number-like objects.
NoQ updated this revision to Diff 74969. NoQ added a comment. - Support conversion though function calls. - Move "if (x == 0)" to pedantic for now (too loud). https://reviews.llvm.org/D22968 Files: include/clang/StaticAnalyzer/Checkers/Checkers.td lib/StaticAnalyzer/Checkers/CMakeLists.txt lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp test/Analysis/Inputs/system-header-simulator-objc.h test/Analysis/number-object-conversion.cpp test/Analysis/number-object-conversion.m Index: test/Analysis/number-object-conversion.m === --- /dev/null +++ test/Analysis/number-object-conversion.m @@ -0,0 +1,86 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -w -analyze -analyzer-checker=osx.NumberObjectConversion %s -verify +// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -w -analyze -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify +// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -fobjc-arc -w -analyze -analyzer-checker=osx.NumberObjectConversion %s -verify +// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -fobjc-arc -w -analyze -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify + +#include "Inputs/system-header-simulator-objc.h" + +void takes_boolean(BOOL); +void takes_integer(int); + +void bad(NSNumber *p) { +#ifdef PEDANTIC + if (p) {} // expected-warning{{Converting 'NSNumber *' to a plain boolean value for branching; please compare the pointer to nil instead to suppress this warning}} + if (!p) {} // expected-warning{{Converting 'NSNumber *' to a plain boolean value for branching; please compare the pointer to nil instead to suppress this warning}} + (!p) ? 1 : 2; // expected-warning{{Converting 'NSNumber *' to a plain boolean value for branching; please compare the pointer to nil instead to suppress this warning}} + (BOOL)p; // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; please compare the pointer to nil instead to suppress this warning}} + if (p == 0) {} // expected-warning{{Converting 'NSNumber *' to a plain integer value; please compare the pointer to nil instead to suppress this warning}} + if (p > 0) {} // expected-warning{{Converting 'NSNumber *' to a plain integer value; pointer value is being used instead}} +#endif + if (p == YES) {} // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} + if (p == NO) {} // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} + BOOL x = p; // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} + x = p; // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} + x = (p == YES); // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} + if (p == 1) {} // expected-warning{{Converting 'NSNumber *' to a plain integer value; pointer value is being used instead}} + int y = p; // expected-warning{{Converting 'NSNumber *' to a plain integer value; pointer value is being used instead}} + y = p; // expected-warning{{Converting 'NSNumber *' to a plain integer value; pointer value is being used instead}} + takes_boolean(p); // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} + takes_integer(p); // expected-warning{{Converting 'NSNumber *' to a plain integer value; pointer value is being used instead}} + takes_boolean(x); // no-warning + takes_integer(y); // no-warning +} + +typedef NSNumber *SugaredNumber; +void bad_sugared(SugaredNumber p) { + p == YES; // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} +} + +@interface I : NSObject { +@public + NSNumber *ivar; + NSNumber *prop; +} +- (NSNumber *)foo; +@property(copy) NSNumber *prop; +@end + +@implementation I +@synthesize prop; +@end + +void bad_ivar(I *i) { + i->ivar == YES; // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} + i->prop == YES; // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} + [i foo] == YES; // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} +} + +void good(NSNumber *p) { + if ([p boolValue] == NO) {} // no-warning + if ([p boolValue] == YES) {} // no-warning + BOOL x = [p boolValue]; // no-warning +} + +void suppression(NSNumber *p) { + if (p == NULL) {} // no-warning + if (p == nil) {} // no-warning +} + +// Conversion of a pointer to an intptr_t is fine. +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long fintptr_t; // Fake, for testing the regex. +void test
[PATCH] D22968: [analyzer] A checker for macOS-specific bool- and number-like objects.
zaks.anna accepted this revision. zaks.anna added inline comments. This revision is now accepted and ready to land. Comment at: include/clang/StaticAnalyzer/Checkers/Checkers.td:479 + InPackage, + HelpText<"Check for erroneous conversions of number pointers into numbers">, + DescFile<"NumberObjectConversionChecker">; "number pointers" -> "objects representing numbers" https://reviews.llvm.org/D22968 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D22968: [analyzer] A checker for macOS-specific bool- and number-like objects.
NoQ updated this revision to Diff 73889. NoQ added a comment. - Rename test files for consistency. - Suppress false positives on `intptr_t`. - Add a triple to the tests to in order to stop worrying about integer types. https://reviews.llvm.org/D22968 Files: include/clang/StaticAnalyzer/Checkers/Checkers.td lib/StaticAnalyzer/Checkers/CMakeLists.txt lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp test/Analysis/Inputs/system-header-simulator-objc.h test/Analysis/number-object-conversion.cpp test/Analysis/number-object-conversion.m Index: test/Analysis/number-object-conversion.m === --- /dev/null +++ test/Analysis/number-object-conversion.m @@ -0,0 +1,79 @@ +// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -w -analyze -analyzer-checker=osx.NumberObjectConversion %s -verify +// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -w -analyze -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify +// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -fobjc-arc -w -analyze -analyzer-checker=osx.NumberObjectConversion %s -verify +// RUN: %clang_cc1 -triple i386-apple-darwin10 -fblocks -fobjc-arc -w -analyze -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify + +#include "Inputs/system-header-simulator-objc.h" + +void bad(NSNumber *p) { +#ifdef PEDANTIC + if (p) {} // expected-warning{{Converting 'NSNumber *' to a plain boolean value for branching; please compare the pointer to nil instead to suppress this warning}} + if (!p) {} // expected-warning{{Converting 'NSNumber *' to a plain boolean value for branching; please compare the pointer to nil instead to suppress this warning}} + (!p) ? 1 : 2; // expected-warning{{Converting 'NSNumber *' to a plain boolean value for branching; please compare the pointer to nil instead to suppress this warning}} + (BOOL)p; // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; please compare the pointer to nil instead to suppress this warning}} +#endif + if (p == YES) {} // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} + if (p == NO) {} // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} + BOOL x = p; // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} + x = p; // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} + x = (p == YES); // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} + if (p == 0) {} // expected-warning{{Converting 'NSNumber *' to a plain integer value; please compare the pointer to nil instead to suppress this warning}} + if (p == 1) {} // expected-warning{{Converting 'NSNumber *' to a plain integer value; pointer value is being used instead}} + if (p > 0) {} // expected-warning{{Converting 'NSNumber *' to a plain integer value; please compare the pointer to nil instead to suppress this warning}} + int y = p; // expected-warning{{Converting 'NSNumber *' to a plain integer value; pointer value is being used instead}} + y = p; // expected-warning{{Converting 'NSNumber *' to a plain integer value; pointer value is being used instead}} +} + +typedef NSNumber *SugaredNumber; +void bad_sugared(SugaredNumber p) { + p == YES; // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} +} + +@interface I : NSObject { +@public + NSNumber *ivar; + NSNumber *prop; +} +- (NSNumber *)foo; +@property(copy) NSNumber *prop; +@end + +@implementation I +@synthesize prop; +@end + +void bad_ivar(I *i) { + i->ivar == YES; // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} + i->prop == YES; // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} + [i foo] == YES; // expected-warning{{Converting 'NSNumber *' to a plain BOOL value; pointer value is being used instead}} +} + +void good(NSNumber *p) { + if ([p boolValue] == NO) {} // no-warning + if ([p boolValue] == YES) {} // no-warning + BOOL x = [p boolValue]; // no-warning +} + +void suppression(NSNumber *p) { + if (p == NULL) {} // no-warning + if (p == nil) {} // no-warning +} + +// Conversion of a pointer to an intptr_t is fine. +typedef long intptr_t; +typedef unsigned long uintptr_t; +typedef long fintptr_t; // Fake, for testing the regex. +void test_intptr_t(NSNumber *p) { + (long)p; // expected-warning{{Converting 'NSNumber *' to a plain integer value; pointer value is being used instead}} + (intptr_t)p; // no-warning + (unsigned long)p; // expected-warning{{Converting 'NSNumber *' to a plain integer value; pointer value is being
Re: [PATCH] D22968: [analyzer] A checker for macOS-specific bool- and number-like objects.
NoQ marked an inline comment as done. NoQ added a comment. Ouch, seems inline answers don't automatically post themselves when you update the diff :o Comment at: lib/StaticAnalyzer/Checkers/BoolConversionChecker.cpp:62 @@ +61,3 @@ + << "' to a plain boolean value: probably a forgotten " + << (IsObjC ? "'[boolValue]'" : "'->isTrue()'"); +BR.EmitBasicReport( dcoughlin wrote: > - The '[boolValue]' thing here is weird. Maybe use '-boolValue' instead? > - How about "Comparison between 'NSNumber *' and 'BOOL'; use -boolValue > instead." > - You probably want to remove lifetime qualifiers from the type with > `.getUnqualifiedType()`. before printing (i.e., don't mention '__strong') in > the diagnostic. > Yeah, noticed the lifetime qualifiers. Changed messages significantly. Comment at: lib/StaticAnalyzer/Checkers/BoolConversionChecker.cpp:117 @@ +116,3 @@ +auto ConversionThroughComparisonM = +binaryOperator(anyOf(hasOperatorName("=="), hasOperatorName("!=")), + hasEitherOperand(NSNumberExprM), zaks.anna wrote: > Can we use any binary operator here without any restrictions? Comparisons are handled here. Assignments are handled in a different matcher. Arithmetic operators are either a valid pointer arithmetic (such as `+` or `-`) or cause compile errors (such as `*` or `/`). Bitwise ops (`&`, `>>`, etc.) - perhaps somebody is computing shadow memory. Logical ops - also too commonly intentional (typically: `if (p && [p boolValue])`). Comma operator - ouch, we should probably warn about the very fact that somebody uses comma operators. Comment at: test/Analysis/bool-conversion.cpp:18 @@ +17,3 @@ +#ifdef PEDANTIC + if (p) {} // expected-warning{{}} + if (!p) {} // expected-warning{{}} zaks.anna wrote: > dcoughlin wrote: > > It is generally good to include the diagnostic text in the test for the > > warning. This way we make sure we get the warning we expected. > +1 > > Are these pedantic because we assume these are comparing the pointer and not > the value? Have you checked that this is a common idiom? > > Same comment applies to NSNumber. If it is common practice to compare against > nil.. > > Are these pedantic because we assume these are comparing the pointer and not > the value? Have you checked that this is a common idiom? I haven't checked if this is more popular or less popular than `if (p == nil)`, but it's clearly too popular and too often correct for a warning enabled by default. Comment at: test/Analysis/bool-conversion.cpp:21 @@ +20,3 @@ + p ? 1 : 2; // expected-warning{{}} + (bool)p; // expected-warning{{}} +#endif zaks.anna wrote: > Why is this OK? Will test more closely; i think this gives a lot of intentionals, but a cast to a non-boolean integer is clearly an error that must be reported. Comment at: test/Analysis/bool-conversion.m:10 @@ +9,3 @@ + if (!p) {} // expected-warning{{}} + if (p == YES) {} // expected-warning{{}} + if (p == NO) {} // expected-warning{{}} zaks.anna wrote: > dcoughlin wrote: > > There is a Sema warning for `p == YES` already, right? ("comparison between > > pointer and integer ('NSNumber *' and 'int')") > These tests seem to be even more relevant to OSBoolean. > There is a Sema warning Yep, but it is disabled with `-w`. I think it's a good idea to add `-w` to the run line in all analyzer tests - it often makes tests easier to read, and in particular we're sure that all warnings in the test are coming from the enabled checkers, not from other sources. Comment at: test/Analysis/bool-conversion.m:11 @@ +10,3 @@ + if (p == YES) {} // expected-warning{{}} + if (p == NO) {} // expected-warning{{}} + (!p) ? 1 : 2; // expected-warning{{}} dcoughlin wrote: > Should `p == NO` be on in non-pedantic mode, as well? It also seems to me > that you could warn on comparison of *any* ObjCObjectPointerType type to > `NO`. At a minimum it would probably be good to check for comparisons of `id` > to NO. Whoops, accidental. https://reviews.llvm.org/D22968 ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
Re: [PATCH] D22968: [analyzer] A checker for macOS-specific bool- and number-like objects.
NoQ retitled this revision from "[analyzer] A checker for macOS-specific bool-like objects." to "[analyzer] A checker for macOS-specific bool- and number-like objects.". NoQ updated the summary for this revision. NoQ updated this revision to Diff 72392. NoQ marked 10 inline comments as done. NoQ added a comment. Herald added subscribers: mgorny, beanz. The checker now checks conversions of `NSNumber` to integer types, not just boolean. To do now - a bit more time needed to test various tweaks. The current version of the non-pedantic checker has found a couple of good new true positives, being relatively silent in general. I'm keeping positives of form `x == 0` (where `x` is a number pointer) in non-pedantic checker, even though they have been reporting non-bugs, because bugs of this form have been found, and it seems very desirable to make the code more specific in this particular case. To do later - consider conversions by passing NSNumber to a function that expects an integer, consider OSNumber and maybe CFNumber(?). https://reviews.llvm.org/D22968 Files: include/clang/StaticAnalyzer/Checkers/Checkers.td lib/StaticAnalyzer/Checkers/CMakeLists.txt lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp test/Analysis/Inputs/system-header-simulator-objc.h test/Analysis/NSNumber-conversion.m test/Analysis/OSBoolean-conversion.cpp Index: test/Analysis/OSBoolean-conversion.cpp === --- /dev/null +++ test/Analysis/OSBoolean-conversion.cpp @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -w -std=c++11 -analyze -analyzer-checker=osx.NumberObjectConversion %s -verify +// RUN: %clang_cc1 -w -std=c++11 -analyze -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify + +#define NULL ((void *)0) +#include "Inputs/system-header-simulator-cxx.h" // for nullptr + +class OSBoolean { +public: + virtual bool isTrue() const; + virtual bool isFalse() const; +}; + +extern const OSBoolean *const &kOSBooleanFalse; +extern const OSBoolean *const &kOSBooleanTrue; + +void bad(const OSBoolean *p) { +#ifdef PEDANTIC + if (p) {} // expected-warning{{Converting 'const class OSBoolean *' to a plain boolean value for branching; please compare the pointer to NULL or nullptr instead to suppress this warning}} + if (!p) {} // expected-warning{{Converting 'const class OSBoolean *' to a plain boolean value for branching; please compare the pointer to NULL or nullptr instead to suppress this warning}} + p ? 1 : 2; // expected-warning{{Converting 'const class OSBoolean *' to a plain boolean value for branching; please compare the pointer to NULL or nullptr instead to suppress this warning}} + (bool)p; // expected-warning{{Converting 'const class OSBoolean *' to a plain bool value; please compare the pointer to NULL or nullptr instead to suppress this warning}} +#endif + bool x = p; // expected-warning{{Converting 'const class OSBoolean *' to a plain bool value; pointer value is being used instead}} + x = p; // expected-warning{{Converting 'const class OSBoolean *' to a plain bool value; pointer value is being used instead}} +} + +typedef bool sugared_bool; +typedef const OSBoolean *sugared_OSBoolean; +void bad_sugared(sugared_OSBoolean p) { + sugared_bool x = p; // expected-warning{{Converting 'const class OSBoolean *' to a plain bool value; pointer value is being used instead}} +} + +void good(const OSBoolean *p) { + bool x = p->isTrue(); // no-warning + (bool)p->isFalse(); // no-warning + if (p == kOSBooleanTrue) {} // no-warning +} + +void suppression(const OSBoolean *p) { + if (p == NULL) {} // no-warning + bool y = (p == nullptr); // no-warning +} + +// Test a different definition of NULL. +#undef NULL +#define NULL 0 +void test_non_pointer_NULL(const OSBoolean *p) { + if (p == NULL) {} // no-warning +} Index: test/Analysis/NSNumber-conversion.m === --- /dev/null +++ test/Analysis/NSNumber-conversion.m @@ -0,0 +1,67 @@ +// RUN: %clang_cc1 -fblocks -w -analyze -analyzer-checker=osx.NumberObjectConversion %s -verify +// RUN: %clang_cc1 -fblocks -w -analyze -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify +// RUN: %clang_cc1 -fblocks -fobjc-arc -w -analyze -analyzer-checker=osx.NumberObjectConversion %s -verify +// RUN: %clang_cc1 -fblocks -fobjc-arc -w -analyze -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify + +#include "Inputs/system-header-simulator-objc.h" + +void bad(NSNumber *p) { +#ifdef PEDANTIC + if (p) {} // expected-warning{{Converting 'NSNumber *' to a plain boolean value for branching; please compare the pointer to nil instead to suppress this warning}} + if (!p) {} // expected-warning{{Converting 'NSNumber *' to a plain boolean value for branching;