blob: a952717e9e2116558af5b6c9dbee7aedfe24291e [file] [log] [blame]
Artem Dergachev940c7702016-10-18 11:06:28 +00001// 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
7class OSBoolean {
8public:
9 virtual bool isTrue() const;
10 virtual bool isFalse() const;
11};
12
13extern const OSBoolean *const &kOSBooleanFalse;
14extern const OSBoolean *const &kOSBooleanTrue;
15
16void takes_bool(bool);
17
18void 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
31typedef bool sugared_bool;
32typedef const OSBoolean *sugared_OSBoolean;
33void 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
37void 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
43void 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.
49typedef long intptr_t;
50typedef unsigned long uintptr_t;
51typedef long fintptr_t; // Fake, for testing the regex.
52void 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
63void test_non_pointer_NULL(const OSBoolean *p) {
64 if (p == NULL) {} // no-warning
65}