1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify %s
2 
3 void clang_analyzer_eval(bool);
4 
5 void usePointer(int * const *);
6 void useReference(int * const &);
7 
testPointer()8 void testPointer() {
9   int x;
10   int *p;
11 
12   p = &x;
13   x = 42;
14   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
15   usePointer(&p);
16   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
17 
18   p = &x;
19   x = 42;
20   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
21   useReference(p);
22   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
23 
24   int * const cp1 = &x;
25   x = 42;
26   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
27   usePointer(&cp1);
28   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
29 
30   int * const cp2 = &x;
31   x = 42;
32   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
33   useReference(cp2);
34   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
35 }
36 
37 
38 struct Wrapper {
39   int *ptr;
40 };
41 
42 void useStruct(Wrapper &w);
43 void useConstStruct(const Wrapper &w);
44 
testPointerStruct()45 void testPointerStruct() {
46   int x;
47   Wrapper w;
48 
49   w.ptr = &x;
50   x = 42;
51   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
52   useStruct(w);
53   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
54 
55   w.ptr = &x;
56   x = 42;
57   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
58   useConstStruct(w);
59   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
60 }
61 
62 
63 struct RefWrapper {
64   int &ref;
65 };
66 
67 void useStruct(RefWrapper &w);
68 void useConstStruct(const RefWrapper &w);
69 
testReferenceStruct()70 void testReferenceStruct() {
71   int x;
72   RefWrapper w = { x };
73 
74   x = 42;
75   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
76   useStruct(w);
77   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
78 }
79 
80 // FIXME: This test is split into two functions because region invalidation
81 // does not preserve reference bindings. <rdar://problem/13320347>
testConstReferenceStruct()82 void testConstReferenceStruct() {
83   int x;
84   RefWrapper w = { x };
85 
86   x = 42;
87   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
88   useConstStruct(w);
89   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
90 }
91 
92 
93 void usePointerPure(int * const *) __attribute__((pure));
94 void usePointerConst(int * const *) __attribute__((const));
95 
testPureConst()96 void testPureConst() {
97   extern int global;
98   int x;
99   int *p;
100 
101   p = &x;
102   x = 42;
103   global = -5;
104   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
105   clang_analyzer_eval(global == -5); // expected-warning{{TRUE}}
106 
107   usePointerPure(&p);
108   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
109   clang_analyzer_eval(global == -5); // expected-warning{{TRUE}}
110 
111   usePointerConst(&p);
112   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
113   clang_analyzer_eval(global == -5); // expected-warning{{TRUE}}
114 
115   usePointer(&p);
116   clang_analyzer_eval(x == 42); // expected-warning{{UNKNOWN}}
117   clang_analyzer_eval(global == -5); // expected-warning{{UNKNOWN}}
118 }
119 
120 
121