Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / Analysis / inlining / InlineObjCInstanceMethod.m
blobef3af72fa93b5337ad5264f5f0801c01b6a6411e
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core.DivideZero,core.DynamicTypePropagation,osx.cocoa.IncompatibleMethodTypes -w -verify %s
3 #include "InlineObjCInstanceMethod.h"
5 typedef const struct __CFString * CFStringRef;
6 typedef const void * CFTypeRef;
7 extern CFTypeRef CFRetain(CFTypeRef cf);
8 extern void CFRelease(CFTypeRef cf);
9 extern CFStringRef getString(void);
11 // Method is defined in the parent; called through self.
12 @interface MyParent : NSObject
13 - (int)getInt;
14 - (const struct __CFString *) testCovariantReturnType __attribute__((cf_returns_retained));
15 @end
16 @implementation MyParent
17 - (int)getInt {
18     return 0;
21 - (CFStringRef) testCovariantReturnType __attribute__((cf_returns_retained)) {
22   CFStringRef Str = ((void*)0);
23   Str = getString();
24   if (Str) {
25     CFRetain(Str);
26   }
27   return Str;
30 @end
32 @interface MyClass : MyParent
33 @end
34 @implementation MyClass
35 - (int)testDynDispatchSelf {
36   int y = [self getInt];
37   return 5/y; // expected-warning {{Division by zero}}
40 // Get the dynamic type info from a cast (from id to MyClass*).
41 + (int)testAllocInit {
42   MyClass *a = [[self alloc] init];
43   return 5/[a getInt]; // expected-warning {{Division by zero}}
46 // Method is called on inited object.
47 + (int)testAllocInit2 {
48   MyClass *a = [[MyClass alloc] init];
49   return 5/[a getInt]; // expected-warning {{Division by zero}}
52 // Method is called on a parameter.
53 + (int)testParam: (MyClass*) a {
54   return 5/[a getInt]; // expected-warning {{Division by zero}}
57 // Method is called on a parameter of unnown type.
58 + (int)testParamUnknownType: (id) a {
59   return 5/[a getInt]; // no warning
62 @end
64 // TODO: When method is inlined, the attribute reset should be visible.
65 @interface TestSettingAnAttributeInCallee : NSObject {
66   int _attribute;
68   - (void) method2;
69 @end
71 @implementation TestSettingAnAttributeInCallee
72 - (int) method1 {
73   [self method2];
74   return 5/_attribute; // expected-warning {{Division by zero}}
77 - (void) method2 {
78   _attribute = 0;
80 @end
82 @interface TestSettingAnAttributeInCaller : NSObject {
83   int _attribute;
85   - (int) method2;
86 @end
88 @implementation TestSettingAnAttributeInCaller
89 - (void) method1 {
90   _attribute = 0;
91   [self method2];
94 - (int) method2 {
95   return 5/_attribute; // expected-warning {{Division by zero}}
97 @end
100 // Don't crash if we don't know the receiver's region.
101 void randomlyMessageAnObject(MyClass *arr[], int i) {
102   (void)[arr[i] getInt];
106 @interface EvilChild : MyParent
107 - (id)getInt;
108 - (const struct __CFString *) testCovariantReturnType __attribute__((cf_returns_retained));
109 @end
111 @implementation EvilChild
112 - (id)getInt { // expected-warning {{types are incompatible}}
113   return self;
115 - (CFStringRef) testCovariantReturnType __attribute__((cf_returns_retained)) {
116   CFStringRef Str = ((void*)0);
117   Str = getString();
118   if (Str) {
119     CFRetain(Str);
120   }
121   return Str;
124 @end
126 int testNonCovariantReturnType(void) {
127   MyParent *obj = [[EvilChild alloc] init];
129   // Devirtualization allows us to directly call -[EvilChild getInt], but
130   // that returns an id, not an int. There is an off-by-default warning for
131   // this, -Woverriding-method-mismatch, and an on-by-default analyzer warning,
132   // osx.cocoa.IncompatibleMethodTypes. This code would probably crash at
133   // runtime, but at least the analyzer shouldn't crash.
134   int x = 1 + [obj getInt];
136   [obj release];
137   return 5/(x-1); // no-warning
140 int testCovariantReturnTypeNoErrorSinceTypesMatch(void) {
141   MyParent *obj = [[EvilChild alloc] init];
143   CFStringRef S = ((void*)0);
144   S = [obj testCovariantReturnType];
145   if (S)
146     CFRelease(S);
147   CFRelease(obj);