misc-ps-region-store.m revision 386af0a224d8943f0c818d66fabc56642a458c8c
1// RUN: clang-cc -triple i386-apple-darwin9 -analyze -checker-cfref --analyzer-store=region --verify -fblocks %s &&
2// RUN: clang-cc -triple x86_64-apple-darwin9 -analyze -checker-cfref --analyzer-store=region --verify -fblocks %s
3
4typedef struct objc_selector *SEL;
5typedef signed char BOOL;
6typedef int NSInteger;
7typedef unsigned int NSUInteger;
8typedef struct _NSZone NSZone;
9@class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
10@protocol NSObject  - (BOOL)isEqual:(id)object; @end
11@protocol NSCopying  - (id)copyWithZone:(NSZone *)zone; @end
12@protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone; @end
13@protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder; @end
14@interface NSObject <NSObject> {} - (id)init; @end
15extern id NSAllocateObject(Class aClass, NSUInteger extraBytes, NSZone *zone);
16@interface NSString : NSObject <NSCopying, NSMutableCopying, NSCoding>
17- (NSUInteger)length;
18+ (id)stringWithUTF8String:(const char *)nullTerminatedCString;
19@end extern NSString * const NSBundleDidLoadNotification;
20@interface NSAssertionHandler : NSObject {}
21+ (NSAssertionHandler *)currentHandler;
22- (void)handleFailureInMethod:(SEL)selector object:(id)object file:(NSString *)fileName lineNumber:(NSInteger)line description:(NSString *)format,...;
23@end
24extern NSString * const NSConnectionReplyMode;
25
26
27//---------------------------------------------------------------------------
28// Test case 'checkaccess_union' differs for region store and basic store.
29// The basic store doesn't reason about compound literals, so the code
30// below won't fire an "uninitialized value" warning.
31//---------------------------------------------------------------------------
32
33// PR 2948 (testcase; crash on VisitLValue for union types)
34// http://llvm.org/bugs/show_bug.cgi?id=2948
35
36void checkaccess_union() {
37  int ret = 0, status;
38  if (((((__extension__ (((union {  // expected-warning {{ Branch condition evaluates to an uninitialized value.}}
39    __typeof (status) __in; int __i;}
40    )
41    {
42      .__in = (status)}
43      ).__i))) & 0xff00) >> 8) == 1)
44        ret = 1;
45}
46
47
48// Check our handling of fields being invalidated by function calls.
49struct test2_struct { int x; int y; char* s; };
50void test2_helper(struct test2_struct* p);
51
52char test2() {
53  struct test2_struct s;
54  test2_help(&s);
55  char *p = 0;
56  
57  if (s.x > 1) {
58    if (s.s != 0) {
59      p = "hello";
60    }
61  }
62  
63  if (s.x > 1) {
64    if (s.s != 0) {
65      return *p;
66    }
67  }
68
69  return 'a';
70}
71
72// BasicStore handles this case incorrectly because it doesn't reason about
73// the value pointed to by 'x' and thus creates different symbolic values
74// at the declarations of 'a' and 'b' respectively.  RegionStore handles
75// it correctly. See the companion test in 'misc-ps-basic-store.m'.
76void test_trivial_symbolic_comparison_pointer_parameter(int *x) {
77  int a = *x;
78  int b = *x;
79  if (a != b) {
80    int *p = 0;
81    *p = 0xDEADBEEF;     // no-warning
82  }
83}
84
85// This is a modified test from 'misc-ps.m'.  Here we have the extra
86// NULL dereferences which are pruned out by RegionStore's symbolic reasoning
87// of fields.
88typedef struct _BStruct { void *grue; } BStruct;
89void testB_aux(void *ptr);
90
91void testB(BStruct *b) {
92  {
93    int *__gruep__ = ((int *)&((b)->grue));
94    int __gruev__ = *__gruep__;
95    int __gruev2__ = *__gruep__;
96    if (__gruev__ != __gruev2__) {
97      int *p = 0;
98      *p = 0xDEADBEEF; // no-warning
99    }
100
101    testB_aux(__gruep__);
102  }
103  {
104    int *__gruep__ = ((int *)&((b)->grue));
105    int __gruev__ = *__gruep__;
106    int __gruev2__ = *__gruep__;
107    if (__gruev__ != __gruev2__) {
108      int *p = 0;
109      *p = 0xDEADBEEF; // no-warning
110    }
111
112    if (~0 != __gruev__) {}
113  }
114}
115
116void testB_2(BStruct *b) {
117  {
118    int **__gruep__ = ((int **)&((b)->grue));
119    int *__gruev__ = *__gruep__;
120    testB_aux(__gruep__);
121  }
122  {
123    int **__gruep__ = ((int **)&((b)->grue));
124    int *__gruev__ = *__gruep__;
125    if ((int*)~0 != __gruev__) {}
126  }
127}
128
129// This test case is a reduced case of a caching bug discovered by an
130// assertion failure in RegionStoreManager::BindArray.  Essentially the
131// DeclStmt is evaluated twice, but on the second loop iteration the
132// engine caches out.  Previously a false transition would cause UnknownVal
133// to bind to the variable, firing an assertion failure.  This bug was fixed
134// in r76262.
135void test_declstmt_caching() {
136again:
137  {
138    const char a[] = "I like to crash";
139    goto again;
140  }
141}
142