inline-defensive-checks.m revision aabb4c5eacca6d78ef778f33ec5cd4c755d71a39
1// RUN: %clang_cc1 -analyze -analyzer-checker=core -analyzer-config suppress-inlined-defensive-checks=true -verify %s
2
3typedef signed char BOOL;
4typedef struct objc_class *Class;
5typedef struct objc_object {
6  Class isa;
7} *id;
8@protocol NSObject  - (BOOL)isEqual:(id)object; @end
9@interface NSObject <NSObject> {}
10+(id)alloc;
11+(id)new;
12-(id)init;
13-(id)autorelease;
14-(id)copy;
15- (Class)class;
16-(id)retain;
17@end
18
19// Check that inline defensive checks is triggered for null expressions
20// within CompoundLiteralExpr.
21typedef union {
22  struct dispatch_object_s *_do;
23  struct dispatch_source_s *_ds;
24} dispatch_object_t __attribute__((__transparent_union__));
25typedef struct dispatch_source_s *dispatch_source_t;
26
27extern __attribute__((visibility("default"))) __attribute__((__nonnull__)) __attribute__((__nothrow__))
28void
29dispatch_resume(dispatch_object_t object);
30
31@interface AppDelegate : NSObject {
32@protected
33	dispatch_source_t p;
34}
35@end
36@implementation AppDelegate
37- (void)updateDeleteTimer {
38	if (p != ((void*)0))
39		;
40}
41- (void)createAndStartDeleteTimer {
42  [self updateDeleteTimer];
43  dispatch_resume(p); // no warning
44}
45@end
46
47// Test nil receiver suppression.
48// We only suppress on nil receiver if the nil value is directly causing the bug.
49@interface Foo {
50@public
51  int x;
52}
53- (Foo *)getFooPtr;
54@end
55
56Foo *retNil() {
57  return 0;
58}
59
60Foo *retInputOrNil(Foo *p) {
61  if (p)
62    return p;
63  return 0;
64}
65
66void idc(Foo *p) {
67  if (p)
68    ;
69}
70
71int testNilReceiver(Foo* fPtr) {
72  if (fPtr)
73    ;
74  // On a path where fPtr is nil, mem should be nil.
75  Foo *mem = [fPtr getFooPtr];
76  return mem->x; // expected-warning {{Access to instance variable 'x' results in a dereference of a null pointer}}
77}
78
79int dontSuppressNilReceiverRetNullCond(Foo* fPtr) {
80  unsigned zero = 0;
81  fPtr = retInputOrNil(fPtr);
82  // On a path where fPtr is nil, mem should be nil.
83  // The warning is not suppressed because the receiver being nil is not
84  // directly related to the value that triggers the warning.
85  Foo *mem = [fPtr getFooPtr];
86  if (!mem)
87    return 5/zero; // expected-warning {{Division by zero}}
88  return 0;
89}
90
91int dontSuppressNilReceiverRetNull(Foo* fPtr) {
92  unsigned zero = 0;
93  fPtr = retNil();
94  // On a path where fPtr is nil, mem should be nil.
95  // The warning is not suppressed because the receiver being nil is not
96  // directly related to the value that triggers the warning.
97  Foo *mem = [fPtr getFooPtr];
98  if (!mem)
99    return 5/zero; // expected-warning {{Division by zero}}
100  return 0;
101}
102
103int dontSuppressNilReceiverIDC(Foo* fPtr) {
104  unsigned zero = 0;
105  idc(fPtr);
106  // On a path where fPtr is nil, mem should be nil.
107  // The warning is not suppressed because the receiver being nil is not
108  // directly related to the value that triggers the warning.
109  Foo *mem = [fPtr getFooPtr];
110  if (!mem)
111    return 5/zero; // expected-warning {{Division by zero}}
112  return 0;
113}
114