aboutsummaryrefslogtreecommitdiff
path: root/test/Analysis/NoReturn.m
blob: 9b7011e793186c5eba6749b6ca9bdfe7a22610e7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify %s

#include <stdarg.h>

//===----------------------------------------------------------------------===//
// The following code is reduced using delta-debugging from
// Foundation.h (Mac OS X).
//
// It includes the basic definitions for the test cases below.
// Not directly including Foundation.h directly makes this test case 
// both svelte and portable to non-Mac platforms.
//===----------------------------------------------------------------------===//

typedef signed char BOOL;
typedef unsigned int NSUInteger;
typedef struct _NSZone NSZone;
@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
@protocol NSObject  - (BOOL)isEqual:(id)object;
@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
@end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
@interface NSObject <NSObject> {} @end
extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
- (NSUInteger)length;
+ (id)stringWithFormat:(NSString *)format, ...;
@end
@interface NSSimpleCString : NSString {} @end
@interface NSConstantString : NSSimpleCString @end
extern void *_NSConstantStringClassReference;
typedef double NSTimeInterval;
@interface NSDate : NSObject <NSCopying, NSCoding>  - (NSTimeInterval)timeIntervalSinceReferenceDate; @end
@class NSString, NSDictionary, NSArray;
@interface NSException : NSObject <NSCopying, NSCoding> {}
+ (NSException *)exceptionWithName:(NSString *)name reason:(NSString *)reason userInfo:(NSDictionary *)userInfo;
- (void)raise;
@end
@interface NSException (NSExceptionRaisingConveniences)
+ (void)raise:(NSString *)name format:(NSString *)format, ...;
+ (void)raise:(NSString *)name format:(NSString *)format arguments:(va_list)argList;
@end

enum {NSPointerFunctionsStrongMemory = (0 << 0),     NSPointerFunctionsZeroingWeakMemory = (1 << 0),     NSPointerFunctionsOpaqueMemory = (2 << 0),     NSPointerFunctionsMallocMemory = (3 << 0),     NSPointerFunctionsMachVirtualMemory = (4 << 0),        NSPointerFunctionsObjectPersonality = (0 << 8),     NSPointerFunctionsOpaquePersonality = (1 << 8),     NSPointerFunctionsObjectPointerPersonality = (2 << 8),     NSPointerFunctionsCStringPersonality = (3 << 8),     NSPointerFunctionsStructPersonality = (4 << 8),     NSPointerFunctionsIntegerPersonality = (5 << 8),      NSPointerFunctionsCopyIn = (1 << 16), };

//===----------------------------------------------------------------------===//
// Test cases.
//===----------------------------------------------------------------------===//

int f1(int *x, NSString* s) {
  
  if (x) ++x;
  
  [NSException raise:@"Blah" format:[NSString stringWithFormat:@"Blah %@", s]];
  
  return *x; // no-warning
}

int f2(int *x, ...) {
  
  if (x) ++x;
  va_list alist;
  va_start(alist, x);
  
  [NSException raise:@"Blah" format:@"Blah %@" arguments:alist];
  
  return *x; // no-warning
}

int f3(int* x) {
  
  if (x) ++x;
  
  [[NSException exceptionWithName:@"My Exception" reason:@"Want to test exceptions." userInfo:0] raise];

  return *x; // no-warning
}


@interface CustomException : NSException
@end

int testCustomException(int *x) {
  if (x != 0) return 0;

  [CustomException raise:@"Blah" format:@"abc"];

  return *x; // no-warning
}

// Test that __attribute__((analyzer_noreturn)) has the intended
// effect on Objective-C methods.

@interface Radar11634353
+ (void) doesNotReturn __attribute__((analyzer_noreturn));
- (void) alsoDoesNotReturn __attribute__((analyzer_noreturn));
@end

void test_rdar11634353() {
  [Radar11634353 doesNotReturn];
  int *p = 0;
  *p = 0xDEADBEEF; // no-warning
}

void test_rdar11634352_instance(Radar11634353 *o) {
  [o alsoDoesNotReturn];
  int *p = 0;
  *p = 0xDEADBEEF; // no-warning
}

void test_rdar11634353_positive() {
  int *p = 0;
  *p = 0xDEADBEEF; // expected-warning {{null pointer}}
}

// Test analyzer_noreturn on category methods.
@interface NSException (OBExtensions)
+ (void)raise:(NSString *)name reason:(NSString *)reason __attribute__((analyzer_noreturn));
@end

void PR11959(int *p) {
  if (!p)
    [NSException raise:@"Bad Pointer" reason:@"Who knows?"];
  *p = 0xDEADBEEF; // no-warning
}

// Test that hard-coded Microsoft _wassert name is recognized as a noreturn
#define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(#_Expression, __FILE__, __LINE__), 0) )
extern void _wassert(const char * _Message, const char *_File, unsigned _Line);
void test_wassert() {
  assert(0);
  int *p = 0;
  *p = 0xDEADBEEF; // no-warning
}