NoReturn.m revision 6973a27866b176b1cf4e3e3ebcf0196e101b85dd
1// RUN: %clang --analyze -Xclang -analyzer-checker=alpha.core -Xclang -verify %s
2
3#include <stdarg.h>
4
5//===----------------------------------------------------------------------===//
6// The following code is reduced using delta-debugging from
7// Foundation.h (Mac OS X).
8//
9// It includes the basic definitions for the test cases below.
10// Not directly including Foundation.h directly makes this test case 
11// both svelte and portable to non-Mac platforms.
12//===----------------------------------------------------------------------===//
13
14typedef signed char BOOL;
15typedef unsigned int NSUInteger;
16typedef struct _NSZone NSZone;
17@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
18@protocol NSObject  - (BOOL)isEqual:(id)object;
19@end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
20@end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
21@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
22@interface NSObject <NSObject> {} @end
23extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
24@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
25- (NSUInteger)length;
26+ (id)stringWithFormat:(NSString *)format, ...;
27@end
28@interface NSSimpleCString : NSString {} @end
29@interface NSConstantString : NSSimpleCString @end
30extern void *_NSConstantStringClassReference;
31typedef double NSTimeInterval;
32@interface NSDate : NSObject <NSCopying, NSCoding>  - (NSTimeInterval)timeIntervalSinceReferenceDate; @end
33@class NSString, NSDictionary, NSArray;
34@interface NSException : NSObject <NSCopying, NSCoding> {}
35+ (NSException *)exceptionWithName:(NSString *)name reason:(NSString *)reason userInfo:(NSDictionary *)userInfo;
36- (void)raise;
37@end
38@interface NSException (NSExceptionRaisingConveniences)
39+ (void)raise:(NSString *)name format:(NSString *)format, ...;
40+ (void)raise:(NSString *)name format:(NSString *)format arguments:(va_list)argList;
41@end
42
43enum {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), };
44
45//===----------------------------------------------------------------------===//
46// Test cases.
47//===----------------------------------------------------------------------===//
48
49int f1(int *x, NSString* s) {
50  
51  if (x) ++x;
52  
53  [NSException raise:@"Blah" format:[NSString stringWithFormat:@"Blah %@", s]];
54  
55  return *x; // no-warning
56}
57
58int f2(int *x, ...) {
59  
60  if (x) ++x;
61  va_list alist;
62  va_start(alist, x);
63  
64  [NSException raise:@"Blah" format:@"Blah %@" arguments:alist];
65  
66  return *x; // no-warning
67}
68
69int f3(int* x) {
70  
71  if (x) ++x;
72  
73  [[NSException exceptionWithName:@"My Exception" reason:@"Want to test exceptions." userInfo:0] raise];
74
75  return *x; // no-warning
76}
77
78
79@interface CustomException : NSException
80@end
81
82int testCustomException(int *x) {
83  if (x != 0) return 0;
84
85  [CustomException raise:@"Blah" format:@"abc"];
86
87  return *x; // no-warning
88}
89
90// Test that __attribute__((analyzer_noreturn)) has the intended
91// effect on Objective-C methods.
92
93@interface Radar11634353
94+ (void) doesNotReturn __attribute__((analyzer_noreturn));
95- (void) alsoDoesNotReturn __attribute__((analyzer_noreturn));
96@end
97
98void test_rdar11634353() {
99  [Radar11634353 doesNotReturn];
100  int *p = 0;
101  *p = 0xDEADBEEF; // no-warning
102}
103
104void test_rdar11634352_instance(Radar11634353 *o) {
105  [o alsoDoesNotReturn];
106  int *p = 0;
107  *p = 0xDEADBEEF; // no-warning
108}
109
110void test_rdar11634353_positive() {
111  int *p = 0;
112  *p = 0xDEADBEEF; // expected-warning {{null pointer}}
113}
114
115// Test analyzer_noreturn on category methods.
116@interface NSException (OBExtensions)
117+ (void)raise:(NSString *)name reason:(NSString *)reason __attribute__((analyzer_noreturn));
118@end
119
120void PR11959(int *p) {
121  if (!p)
122    [NSException raise:@"Bad Pointer" reason:@"Who knows?"];
123  *p = 0xDEADBEEF; // no-warning
124}
125
126// Test that hard-coded Microsoft _wassert name is recognized as a noreturn
127#define assert(_Expression) (void)( (!!(_Expression)) || (_wassert(#_Expression, __FILE__, __LINE__), 0) )
128extern void _wassert(const char * _Message, const char *_File, unsigned _Line);
129void test_wassert() {
130  assert(0);
131  int *p = 0;
132  *p = 0xDEADBEEF; // no-warning
133}
134