]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - test/Analysis/number-object-conversion.m
Vendor import of clang trunk r300422:
[FreeBSD/FreeBSD.git] / test / Analysis / number-object-conversion.m
1 // RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -fblocks -w -analyzer-checker=osx.NumberObjectConversion %s -verify
2 // RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -fblocks -w -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
3 // RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -fblocks -fobjc-arc -w -analyzer-checker=osx.NumberObjectConversion %s -verify
4 // RUN: %clang_analyze_cc1 -triple i386-apple-darwin10 -fblocks -fobjc-arc -w -analyzer-checker=osx.NumberObjectConversion -analyzer-config osx.NumberObjectConversion:Pedantic=true -DPEDANTIC %s -verify
5
6 #include "Inputs/system-header-simulator-objc.h"
7
8 void takes_boolean(BOOL);
9 void takes_integer(int);
10
11 void bad(NSNumber *p) {
12 #ifdef PEDANTIC
13   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 #else
18   if (p) {} // no-warning
19   if (!p) {} // no-warning
20   (!p) ? 1 : 2; // no-warning
21   if (p == 0) {} // no-warning
22 #endif
23   (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-warning
36   takes_integer(y); // no-warning
37 }
38
39 typedef NSNumber *SugaredNumber;
40 void 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 @public
46   NSNumber *ivar;
47   NSNumber *prop;
48 }
49 - (NSNumber *)foo;
50 @property(copy) NSNumber *prop;
51 @end
52
53 @implementation I
54 @synthesize prop;
55 @end
56
57 void 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
63 void good(NSNumber *p) {
64   if ([p boolValue] == NO) {} // no-warning
65   if ([p boolValue] == YES) {} // no-warning
66   BOOL x = [p boolValue]; // no-warning
67 }
68
69 void suppression(NSNumber *p) {
70   if (p == NULL) {} // no-warning
71   if (p == nil) {} // no-warning
72 }
73
74 // Conversion of a pointer to an intptr_t is fine.
75 typedef long intptr_t;
76 typedef unsigned long uintptr_t;
77 typedef long fintptr_t; // Fake, for testing the regex.
78 void 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-warning
81   (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-warning
83   (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 0
88 #define BAR 1
89 void 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 PEDANTIC
92   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 #else
94   if (p != FOO) {} // no-warning
95 #endif
96 }
97
98 #define NULL_INSIDE_MACRO NULL
99 void test_NULL_inside_macro(NSNumber *p) {
100 #ifdef PEDANTIC
101   if (p == NULL_INSIDE_MACRO) {} // no-warning
102 #else
103   if (p == NULL_INSIDE_MACRO) {} // no-warning
104 #endif
105 }
106
107 // Test a different definition of NULL.
108 #undef NULL
109 #define NULL 0
110 void test_non_pointer_NULL(NSNumber *p) {
111   if (p == NULL) {} // no-warning
112 }