brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.5 KiB · ef3af72 Raw
149 lines · plain
1// RUN: %clang_analyze_cc1 -analyzer-checker=core.DivideZero,core.DynamicTypePropagation,osx.cocoa.IncompatibleMethodTypes -w -verify %s2 3#include "InlineObjCInstanceMethod.h"4 5typedef const struct __CFString * CFStringRef;6typedef const void * CFTypeRef;7extern CFTypeRef CFRetain(CFTypeRef cf);8extern void CFRelease(CFTypeRef cf);9extern CFStringRef getString(void);10 11// Method is defined in the parent; called through self.12@interface MyParent : NSObject13- (int)getInt;14- (const struct __CFString *) testCovariantReturnType __attribute__((cf_returns_retained));15@end16@implementation MyParent17- (int)getInt {18    return 0;19}20 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;28}29 30@end31 32@interface MyClass : MyParent33@end34@implementation MyClass35- (int)testDynDispatchSelf {36  int y = [self getInt];37  return 5/y; // expected-warning {{Division by zero}}38}39 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}}44}45 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}}50}51 52// Method is called on a parameter.53+ (int)testParam: (MyClass*) a {54  return 5/[a getInt]; // expected-warning {{Division by zero}}55}56 57// Method is called on a parameter of unnown type.58+ (int)testParamUnknownType: (id) a {59  return 5/[a getInt]; // no warning60}61 62@end63 64// TODO: When method is inlined, the attribute reset should be visible.65@interface TestSettingAnAttributeInCallee : NSObject {66  int _attribute;67}68  - (void) method2;69@end70 71@implementation TestSettingAnAttributeInCallee72- (int) method1 {73  [self method2];74  return 5/_attribute; // expected-warning {{Division by zero}}75}76 77- (void) method2 {78  _attribute = 0;79}80@end81 82@interface TestSettingAnAttributeInCaller : NSObject {83  int _attribute;84}85  - (int) method2;86@end87 88@implementation TestSettingAnAttributeInCaller89- (void) method1 {90  _attribute = 0;91  [self method2];92}93 94- (int) method2 {95  return 5/_attribute; // expected-warning {{Division by zero}}96}97@end98 99 100// Don't crash if we don't know the receiver's region.101void randomlyMessageAnObject(MyClass *arr[], int i) {102  (void)[arr[i] getInt];103}104 105 106@interface EvilChild : MyParent107- (id)getInt;108- (const struct __CFString *) testCovariantReturnType __attribute__((cf_returns_retained));109@end110 111@implementation EvilChild112- (id)getInt { // expected-warning {{types are incompatible}}113  return self;114}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;122}123 124@end125 126int testNonCovariantReturnType(void) {127  MyParent *obj = [[EvilChild alloc] init];128 129  // Devirtualization allows us to directly call -[EvilChild getInt], but130  // that returns an id, not an int. There is an off-by-default warning for131  // this, -Woverriding-method-mismatch, and an on-by-default analyzer warning,132  // osx.cocoa.IncompatibleMethodTypes. This code would probably crash at133  // runtime, but at least the analyzer shouldn't crash.134  int x = 1 + [obj getInt];135 136  [obj release];137  return 5/(x-1); // no-warning138}139 140int testCovariantReturnTypeNoErrorSinceTypesMatch(void) {141  MyParent *obj = [[EvilChild alloc] init];142 143  CFStringRef S = ((void*)0);144  S = [obj testCovariantReturnType];145  if (S)146    CFRelease(S);147  CFRelease(obj);148}149