95 lines · cpp
1// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -w -std=c++11 -analyzer-checker=osx.NumberObjectConversion %s -verify2// RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -w -std=c++11 -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify3 4#define NULL ((void *)0)5#include "Inputs/system-header-simulator-cxx.h" // for nullptr6 7class OSBoolean {8public:9 virtual bool isTrue() const;10 virtual bool isFalse() const;11};12 13class OSNumber {14public:15 virtual bool isEqualTo(const OSNumber *);16 virtual unsigned char unsigned8BitValue() const;17 virtual unsigned short unsigned16BitValue() const;18 virtual unsigned int unsigned32BitValue() const;19 virtual unsigned long long unsigned64BitValue() const;20};21 22extern const OSBoolean *const &kOSBooleanFalse;23extern const OSBoolean *const &kOSBooleanTrue;24 25void takes_bool(bool);26 27void bad_boolean(const OSBoolean *p) {28#ifdef PEDANTIC29 if (p) {} // expected-warning{{Converting a pointer value of type 'class OSBoolean *' to a primitive boolean value; instead, either compare the pointer to nullptr or call getValue()}}30 if (!p) {} // expected-warning{{Converting a pointer value of type 'class OSBoolean *' to a primitive boolean value; instead, either compare the pointer to nullptr or call getValue()}}31 p ? 1 : 2; // expected-warning{{Converting a pointer value of type 'class OSBoolean *' to a primitive boolean value; instead, either compare the pointer to nullptr or call getValue()}}32#else33 if (p) {} // no-warning34 if (!p) {} // no-warning35 p ? 1 : 2; // no-warning36#endif37 (bool)p; // expected-warning{{Converting a pointer value of type 'class OSBoolean *' to a primitive bool value; did you mean to call getValue()?}}38 bool x = p; // expected-warning{{Converting a pointer value of type 'class OSBoolean *' to a primitive bool value; did you mean to call getValue()?}}39 x = p; // expected-warning{{Converting a pointer value of type 'class OSBoolean *' to a primitive bool value; did you mean to call getValue()?}}40 takes_bool(p); // expected-warning{{Converting a pointer value of type 'class OSBoolean *' to a primitive bool value; did you mean to call getValue()?}}41 takes_bool(x); // no-warning42}43 44void bad_number(const OSNumber *p) {45#ifdef PEDANTIC46 if (p) {} // expected-warning{{Converting a pointer value of type 'class OSNumber *' to a scalar boolean value; instead, either compare the pointer to nullptr or call a method on 'class OSNumber *' to get the scalar value}}47 if (!p) {} // expected-warning{{Converting a pointer value of type 'class OSNumber *' to a scalar boolean value; instead, either compare the pointer to nullptr or call a method on 'class OSNumber *' to get the scalar value}}48 p ? 1 : 2; // expected-warning{{Converting a pointer value of type 'class OSNumber *' to a scalar boolean value; instead, either compare the pointer to nullptr or call a method on 'class OSNumber *' to get the scalar value}}49 if (p == 0) {} // expected-warning{{Comparing a pointer value of type 'class OSNumber *' to a scalar integer value; instead, either compare the pointer to nullptr or compare the result of calling a method on 'class OSNumber *' to get the scalar value}}50#else51 if (p) {} // no-warning52 if (!p) {} // no-warning53 p ? 1 : 2; // no-warning54 if (p == 0) {} // no-warning55#endif56 (int)p; // expected-warning{{Converting a pointer value of type 'class OSNumber *' to a scalar integer value; did you mean to call a method on 'class OSNumber *' to get the scalar value?}}57 takes_bool(p); // expected-warning{{Converting a pointer value of type 'class OSNumber *' to a scalar bool value; did you mean to call a method on 'class OSNumber *' to get the scalar value?}}58}59 60typedef bool sugared_bool;61typedef const OSBoolean *sugared_OSBoolean;62void bad_sugared(sugared_OSBoolean p) {63 sugared_bool x = p; // expected-warning{{Converting a pointer value of type 'class OSBoolean *' to a primitive bool value; did you mean to call getValue()?}}64}65 66void good(const OSBoolean *p) {67 bool x = p->isTrue(); // no-warning68 (bool)p->isFalse(); // no-warning69 if (p == kOSBooleanTrue) {} // no-warning70}71 72void suppression(const OSBoolean *p) {73 if (p == NULL) {} // no-warning74 bool y = (p == nullptr); // no-warning75}76 77// Conversion of a pointer to an intptr_t is fine.78typedef long intptr_t;79typedef unsigned long uintptr_t;80typedef long fintptr_t; // Fake, for testing the regex.81void test_intptr_t(const OSBoolean *p) {82 (long)p; // expected-warning{{Converting a pointer value of type 'class OSBoolean *' to a primitive integer value; did you mean to call getValue()?}}83 (intptr_t)p; // no-warning84 (unsigned long)p; // expected-warning{{Converting a pointer value of type 'class OSBoolean *' to a primitive integer value; did you mean to call getValue()?}}85 (uintptr_t)p; // no-warning86 (fintptr_t)p; // expected-warning{{Converting a pointer value of type 'class OSBoolean *' to a primitive integer value; did you mean to call getValue()?}}87}88 89// Test a different definition of NULL.90#undef NULL91#define NULL 092void test_non_pointer_NULL(const OSBoolean *p) {93 if (p == NULL) {} // no-warning94}95