1// RUN: %clang_analyze_cc1 -fobjc-arc -analyzer-checker=core,debug.ExprInspection -verify %s
2
3void clang_analyzer_eval(int);
4void clang_analyzer_warnIfReached();
5
6extern void __assert_fail (__const char *__assertion, __const char *__file,
7    unsigned int __line, __const char *__function)
8     __attribute__ ((__noreturn__));
9
10#define assert(expr) \
11  ((expr)  ? (void)(0)  : __assert_fail (#expr, __FILE__, __LINE__, __func__))
12
13
14@protocol NSObject
15+ (nonnull instancetype)alloc;
16- (nonnull instancetype)init;
17@end
18@interface NSObject <NSObject> {}
19@end
20
21@interface NSError : NSObject {
22@public
23  int x;
24}
25@end
26
27
28@interface SomeClass : NSObject
29+ (int)doSomethingWithError:(NSError *__autoreleasing *)error;
30@end
31
32@implementation SomeClass
33+ (int)doSomethingWithError:(NSError *__autoreleasing *)error {
34    if (error) {
35        NSError *e = [[NSError alloc] init];
36        assert(e);
37        e->x = 5;
38        *error = e;
39        clang_analyzer_eval(*error != 0); // expected-warning{{TRUE}}
40    }
41    return 0;
42}
43@end
44
45void testStrongOutParam(void) {
46  NSError *error;
47  clang_analyzer_eval(error != 0); // expected-warning{{FALSE}}
48  int ok = [SomeClass doSomethingWithError:&error];
49  clang_analyzer_eval(ok);         // expected-warning{{FALSE}}
50  clang_analyzer_eval(error != 0); // expected-warning{{TRUE}}
51  clang_analyzer_eval(error->x == 5); // expected-warning{{TRUE}}
52}
53
54void testAutoreleasingOutParam(void) {
55  NSError *__autoreleasing error;
56  clang_analyzer_eval(error != 0); // expected-warning{{FALSE}}
57  int ok = [SomeClass doSomethingWithError:&error];
58  clang_analyzer_eval(ok);         // expected-warning{{FALSE}}
59  clang_analyzer_eval(error != 0); // expected-warning{{TRUE}}
60  clang_analyzer_eval(error->x == 5); // expected-warning{{TRUE}}
61}
62
63void testNilOutParam(void) {
64    int ok = [SomeClass doSomethingWithError:(void *)0];
65    clang_analyzer_eval(ok);  // expected-warning{{FALSE}}
66}
67
68