113 lines · plain
1// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -fblocks -w -Wno-int-conversion -analyzer-checker=osx.NumberObjectConversion %s -verify2// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -fblocks -w -Wno-int-conversion -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify3// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -fblocks -fobjc-arc -w -Wno-int-conversion -analyzer-checker=osx.NumberObjectConversion %s -verify4// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -fblocks -fobjc-arc -w -Wno-int-conversion -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify5 6#include "Inputs/system-header-simulator-objc.h"7 8void takes_boolean(BOOL);9void takes_integer(int);10 11void bad(NSNumber *p) {12#ifdef PEDANTIC13 if (p) {} // expected-warning{{Converting a pointer value of type 'NSNumber *' to a primitive boolean value; instead, either compare the pointer to nil or call -boolValue}}14 if (!p) {} // expected-warning{{Converting a pointer value of type 'NSNumber *' to a primitive boolean value; instead, either compare the pointer to nil or call -boolValue}}15 (!p) ? 1 : 2; // expected-warning{{Converting a pointer value of type 'NSNumber *' to a primitive boolean value; instead, either compare the pointer to nil or call -boolValue}}16 if (p == 0) {} // expected-warning{{Comparing a pointer value of type 'NSNumber *' to a scalar integer value; instead, either compare the pointer to nil or compare the result of calling a method on 'NSNumber *' to get the scalar value}}17#else18 if (p) {} // no-warning19 if (!p) {} // no-warning20 (!p) ? 1 : 2; // no-warning21 if (p == 0) {} // no-warning22#endif23 (BOOL)p; // expected-warning{{Converting a pointer value of type 'NSNumber *' to a primitive BOOL value; did you mean to call -boolValue?}}24 if (p > 0) {} // expected-warning{{Comparing a pointer value of type 'NSNumber *' to a scalar integer value; did you mean to compare the result of calling a method on 'NSNumber *' to get the scalar value?}}25 if (p == YES) {} // expected-warning{{Comparing a pointer value of type 'NSNumber *' to a primitive BOOL value; did you mean to compare the result of calling -boolValue?}}26 if (p == NO) {} // expected-warning{{Comparing a pointer value of type 'NSNumber *' to a primitive BOOL value; did you mean to compare the result of calling -boolValue?}}27 BOOL x = p; // expected-warning{{Converting a pointer value of type 'NSNumber *' to a primitive BOOL value; did you mean to call -boolValue?}}28 x = p; // expected-warning{{Converting a pointer value of type 'NSNumber *' to a primitive BOOL value; did you mean to call -boolValue?}}29 x = (p == YES); // expected-warning{{Comparing a pointer value of type 'NSNumber *' to a primitive BOOL value; did you mean to compare the result of calling -boolValue?}}30 if (p == 1) {} // expected-warning{{Comparing a pointer value of type 'NSNumber *' to a scalar integer value; did you mean to compare the result of calling a method on 'NSNumber *' to get the scalar value?}}31 int y = p; // expected-warning{{Converting a pointer value of type 'NSNumber *' to a scalar integer value; did you mean to call a method on 'NSNumber *' to get the scalar value?}}32 y = p; // expected-warning{{Converting a pointer value of type 'NSNumber *' to a scalar integer value; did you mean to call a method on 'NSNumber *' to get the scalar value?}}33 takes_boolean(p); // expected-warning{{Converting a pointer value of type 'NSNumber *' to a primitive BOOL value; did you mean to call -boolValue?}}34 takes_integer(p); // expected-warning{{Converting a pointer value of type 'NSNumber *' to a scalar integer value; did you mean to call a method on 'NSNumber *' to get the scalar value?}}35 takes_boolean(x); // no-warning36 takes_integer(y); // no-warning37}38 39typedef NSNumber *SugaredNumber;40void bad_sugared(SugaredNumber p) {41 p == YES; // expected-warning{{Comparing a pointer value of type 'SugaredNumber' to a primitive BOOL value; did you mean to compare the result of calling -boolValue?}}42}43 44@interface I : NSObject {45@public46 NSNumber *ivar;47 NSNumber *prop;48}49- (NSNumber *)foo;50@property(copy) NSNumber *prop;51@end52 53@implementation I54@synthesize prop;55@end56 57void bad_ivar(I *i) {58 i->ivar == YES; // expected-warning{{Comparing a pointer value of type 'NSNumber *' to a primitive BOOL value; did you mean to compare the result of calling -boolValue?}}59 i->prop == YES; // expected-warning{{Comparing a pointer value of type 'NSNumber *' to a primitive BOOL value; did you mean to compare the result of calling -boolValue?}}60 [i foo] == YES; // expected-warning{{Comparing a pointer value of type 'NSNumber *' to a primitive BOOL value; did you mean to compare the result of calling -boolValue?}}61}62 63void good(NSNumber *p) {64 if ([p boolValue] == NO) {} // no-warning65 if ([p boolValue] == YES) {} // no-warning66 BOOL x = [p boolValue]; // no-warning67}68 69void suppression(NSNumber *p) {70 if (p == NULL) {} // no-warning71 if (p == nil) {} // no-warning72}73 74// Conversion of a pointer to an intptr_t is fine.75typedef long intptr_t;76typedef unsigned long uintptr_t;77typedef long fintptr_t; // Fake, for testing the regex.78void test_intptr_t(NSNumber *p) {79 (long)p; // expected-warning{{Converting a pointer value of type 'NSNumber *' to a scalar integer value; did you mean to call a method on 'NSNumber *' to get the scalar value?}}80 (intptr_t)p; // no-warning81 (unsigned long)p; // expected-warning{{Converting a pointer value of type 'NSNumber *' to a scalar integer value; did you mean to call a method on 'NSNumber *' to get the scalar value?}}82 (uintptr_t)p; // no-warning83 (fintptr_t)p; // expected-warning{{Converting a pointer value of type 'NSNumber *' to a scalar integer value; did you mean to call a method on 'NSNumber *' to get the scalar value?}}84}85 86// Test macro suppressions.87#define FOO 088#define BAR 189void test_macro(NSNumber *p) {90 if (p != BAR) {} // expected-warning{{Comparing a pointer value of type 'NSNumber *' to a scalar integer value; did you mean to compare the result of calling a method on 'NSNumber *' to get the scalar value?}}91#ifdef PEDANTIC92 if (p != FOO) {} // expected-warning{{Comparing a pointer value of type 'NSNumber *' to a scalar integer value; instead, either compare the pointer to nil or compare the result of calling a method on 'NSNumber *' to get the scalar value}}93#else94 if (p != FOO) {} // no-warning95#endif96}97 98#define NULL_INSIDE_MACRO NULL99void test_NULL_inside_macro(NSNumber *p) {100#ifdef PEDANTIC101 if (p == NULL_INSIDE_MACRO) {} // no-warning102#else103 if (p == NULL_INSIDE_MACRO) {} // no-warning104#endif105}106 107// Test a different definition of NULL.108#undef NULL109#define NULL 0110void test_non_pointer_NULL(NSNumber *p) {111 if (p == NULL) {} // no-warning112}113