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