1 // RUN: %clang_cc1 -triple i386-apple-darwin10 -w -std=c++11 -analyze -analyzer-checker=osx.NumberObjectConversion %s -verify 2 // 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 3 4 #define NULL ((void *)0) 5 #include "Inputs/system-header-simulator-cxx.h" // for nullptr 6 7 class OSBoolean { 8 public: 9 virtual bool isTrue() const; 10 virtual bool isFalse() const; 11 }; 12 13 extern const OSBoolean *const &kOSBooleanFalse; 14 extern const OSBoolean *const &kOSBooleanTrue; 15 16 void takes_bool(bool); 17 18 void bad(const OSBoolean *p) { 19 #ifdef PEDANTIC 20 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}} 21 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}} 22 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}} 23 (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}} 24 #endif 25 bool x = p; // expected-warning{{Converting 'const class OSBoolean *' to a plain bool value; pointer value is being used instead}} 26 x = p; // expected-warning{{Converting 'const class OSBoolean *' to a plain bool value; pointer value is being used instead}} 27 takes_bool(p); // expected-warning{{Converting 'const class OSBoolean *' to a plain bool value; pointer value is being used instead}} 28 takes_bool(x); // no-warning 29 } 30 31 typedef bool sugared_bool; 32 typedef const OSBoolean *sugared_OSBoolean; 33 void bad_sugared(sugared_OSBoolean p) { 34 sugared_bool x = p; // expected-warning{{Converting 'const class OSBoolean *' to a plain bool value; pointer value is being used instead}} 35 } 36 37 void good(const OSBoolean *p) { 38 bool x = p->isTrue(); // no-warning 39 (bool)p->isFalse(); // no-warning 40 if (p == kOSBooleanTrue) {} // no-warning 41 } 42 43 void suppression(const OSBoolean *p) { 44 if (p == NULL) {} // no-warning 45 bool y = (p == nullptr); // no-warning 46 } 47 48 // Conversion of a pointer to an intptr_t is fine. 49 typedef long intptr_t; 50 typedef unsigned long uintptr_t; 51 typedef long fintptr_t; // Fake, for testing the regex. 52 void test_intptr_t(const OSBoolean *p) { 53 (long)p; // expected-warning{{Converting 'const class OSBoolean *' to a plain integer value; pointer value is being used instead}} 54 (intptr_t)p; // no-warning 55 (unsigned long)p; // expected-warning{{Converting 'const class OSBoolean *' to a plain integer value; pointer value is being used instead}} 56 (uintptr_t)p; // no-warning 57 (fintptr_t)p; // expected-warning{{Converting 'const class OSBoolean *' to a plain integer value; pointer value is being used instead}} 58 } 59 60 // Test a different definition of NULL. 61 #undef NULL 62 #define NULL 0 63 void test_non_pointer_NULL(const OSBoolean *p) { 64 if (p == NULL) {} // no-warning 65 } 66