[clang] Handle __declspec() attributes in using
[llvm-project.git] / clang / test / Analysis / misc-ps-eager-assume.m
blob38f46b73e703ce5ea5f297addc491836e865c0cf
1 // RUN: %clang_analyze_cc1 -analyzer-checker=core,alpha.core -verify -fblocks %s
2 // expected-no-diagnostics
4 // Delta-reduced header stuff (needed for test cases).
5 typedef signed char BOOL;
6 typedef unsigned int NSUInteger;
7 typedef struct _NSZone NSZone;
8 @class NSInvocation, NSMethodSignature, NSCoder, NSString, NSEnumerator;
9 @protocol NSObject  - (BOOL)isEqual:(id)object;
10 - (oneway void)release;
11 @end  @protocol NSCopying  - (id)copyWithZone:(NSZone *)zone;
12 @end  @protocol NSMutableCopying  - (id)mutableCopyWithZone:(NSZone *)zone;
13 @end  @protocol NSCoding  - (void)encodeWithCoder:(NSCoder *)aCoder;
14 @end    @interface NSObject <NSObject> {}
15 + (id)alloc;
16 - (id)init;
17 @end  typedef struct {}
18 NSFastEnumerationState;
19 @protocol NSFastEnumeration  - (NSUInteger)countByEnumeratingWithState:(NSFastEnumerationState *)state objects:(id *)stackbuf count:(NSUInteger)len;
20 @end      @interface NSArray : NSObject <NSCopying, NSMutableCopying, NSCoding, NSFastEnumeration>  - (NSUInteger)count;
21 @end    @interface NSMutableArray : NSArray  - (void)addObject:(id)anObject;
22 - (BOOL)isEqualToString:(NSString *)aString;
23 @end        @interface NSAutoreleasePool : NSObject {}
24 - (void)drain;
25 - (id)init;
26 @end
28 // This test case tests that (x != 0) is eagerly evaluated before stored to
29 // 'y'.  This test case complements recoverCastedSymbol (see below) because
30 // the symbolic expression is stored to 'y' (which is a short instead of an
31 // int).  recoverCastedSymbol() only recovers path-sensitivity when the
32 // symbolic expression is literally the branch condition.
34 void handle_assign_of_condition(int x) {
35   // The cast to 'short' causes us to lose symbolic constraint.
36   short y = (x != 0);
37   char *p = 0;
38   if (y) {
39     // This should be infeasible.
40     if (!(x != 0)) {
41       *p = 1;  // no-warning
42     }
43   }
46 // From <rdar://problem/6619921>
48 // In this test case, 'needsAnArray' is a signed char.  The analyzer tracks
49 // a symbolic value for this variable, but in the branch condition it is
50 // promoted to 'int'.  Currently the analyzer doesn't reason well about
51 // promotions of symbolic values, so this test case tests the logic in
52 // 'recoverCastedSymbol()' (ExprEngine.cpp) to test that we recover
53 // path-sensitivity and use the symbol for 'needsAnArray' in the branch
54 // condition.
56 void handle_symbolic_cast_in_condition(void) {
57   NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
59   BOOL needsAnArray = [@"aString" isEqualToString:@"anotherString"];
60   NSMutableArray* array = needsAnArray ? [[NSMutableArray alloc] init] : 0;
61   if(needsAnArray)
62     [array release];
64   [pool drain];
67 // From PR 3836 (http://llvm.org/bugs/show_bug.cgi?id=3836)
69 // In this test case, the double '!' works fine with our symbolic constraints,
70 // but we don't support comparing SymConstraint != SymConstraint.  By eagerly
71 // assuming the truth of !!a or !!b, we can compare these values directly.
73 void pr3836(int *a, int *b) {
74   if (!!a != !!b) /* one of them is NULL */
75     return;
76   if (!a && !b) /* both are NULL */
77     return;
78       
79   *a = 1; // no-warning
80   *b = 1; // no-warning
84 //===---------------------------------------------------------------------===//
85 // <rdar://problem/7342806>
86 // This false positive occurred because the symbolic constraint on a short was
87 // not maintained via sign extension.  The analyzer doesn't properly handle
88 // the sign extension, but now tracks the constraint.  This particular
89 // case relies on -analyzer-options eagerly-assume=true because of the expression
90 // 'Flag1 != Count > 0'.
91 //===---------------------------------------------------------------------===//
93 void rdar7342806_aux(short x);
95 void rdar7342806(void) {
96   extern short Count;
97   extern short Flag1;
99   short *Pointer = 0;
100   short  Flag2   = !!Pointer;   // Flag2 is false (0).
101   short  Ok      = 1;
102   short  Which;
104   if( Flag1 != Count > 0 )
105     // Static analyzer skips this so either
106     //   Flag1 is true and Count > 0
107     // or
108     //   Flag1 is false and Count <= 0
109     Ok = 0;
111   if( Flag1 != Flag2 )
112     // Analyzer skips this so Flag1 and Flag2 have the
113     // same value, both are false because Flag2 is false. And
114     // from that we know Count must be <= 0.
115     Ok = 0;
117   for( Which = 0;
118          Which < Count && Ok;
119            Which++ )
120     // This statement can only execute if Count > 0 which can only
121     // happen when Flag1 and Flag2 are both true and Flag2 will only
122     // be true when Pointer is not NULL.
123     rdar7342806_aux(*Pointer); // no-warning
126 //===---------------------------------------------------------------------===//
127 // PR 5627 - http://llvm.org/bugs/show_bug.cgi?id=5627
128 //  This test case depends on using -analyzer-config eagerly-assume=true.
129 //  The 'eagerly-assume=true' causes the path
130 //  to bifurcate when evaluating the function call argument, and a state
131 //  caching bug in ExprEngine::CheckerVisit (and friends) caused the store
132 //  to 'p' to not be evaluated along one path, but then an autotransition caused
133 //  the path to keep on propagating with 'p' still set to an undefined value.
134 //  We would then get a bogus report of returning uninitialized memory.
135 //  Note: CheckerVisit mistakenly cleared an existing node, and the cleared
136 //  node was resurrected by GRStmtNodeBuilder::~GRStmtNodeBuilder(), where
137 //  'p' was not assigned.
138 //===---------------------------------------------------------------------===//
140 float *pr5627_f(int y);
142 float *pr5627_g(int x) {
143   float *p;
144   p = pr5627_f(!x);
145   return p; // no-warning