xref: /llvm-project/clang/test/Analysis/array-struct-region.cpp (revision 19ed6748ea2ff303040702cc6043b9a0c6ca9ce1)
1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c %s
2 // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c++ -analyzer-config c++-inlining=constructors %s
3 // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c %s
4 // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c++ -analyzer-config c++-inlining=constructors %s
5 
6 void clang_analyzer_eval(int);
7 
8 struct S {
9   int field;
10 
11 #if __cplusplus
12   const struct S *getThis() const { return this; }
13 #endif
14 };
15 
16 #ifdef INLINE
17 struct S getS() {
18   struct S s = { 42 };
19   return s;
20 }
21 #else
22 struct S getS();
23 #endif
24 
25 
26 void testAssignment() {
27   struct S s = getS();
28 
29   if (s.field != 42) return;
30   clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}}
31 
32   s.field = 0;
33   clang_analyzer_eval(s.field == 0); // expected-warning{{TRUE}}
34 
35 #if __cplusplus
36   clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}}
37 #endif
38 }
39 
40 
41 void testImmediateUse() {
42   int x = getS().field;
43 
44   if (x != 42) return;
45   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
46 
47 #if __cplusplus
48   clang_analyzer_eval((void *)getS().getThis() == (void *)&x); // expected-warning{{FALSE}}
49 #endif
50 }
51 
52 int getConstrainedField(struct S s) {
53   if (s.field != 42) return 42;
54   return s.field;
55 }
56 
57 int getAssignedField(struct S s) {
58   s.field = 42;
59   return s.field;
60 }
61 
62 void testArgument() {
63   clang_analyzer_eval(getConstrainedField(getS()) == 42); // expected-warning{{TRUE}}
64   clang_analyzer_eval(getAssignedField(getS()) == 42); // expected-warning{{TRUE}}
65 }
66 
67 
68 //--------------------
69 // C++-only tests
70 //--------------------
71 
72 #if __cplusplus
73 void testReferenceAssignment() {
74   const S &s = getS();
75 
76   if (s.field != 42) return;
77   clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}}
78 
79   clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}}
80 }
81 
82 
83 int getConstrainedFieldRef(const S &s) {
84   if (s.field != 42) return 42;
85   return s.field;
86 }
87 
88 bool checkThis(const S &s) {
89   return s.getThis() == &s;
90 }
91 
92 void testReferenceArgument() {
93   clang_analyzer_eval(getConstrainedFieldRef(getS()) == 42); // expected-warning{{TRUE}}
94   clang_analyzer_eval(checkThis(getS())); // expected-warning{{TRUE}}
95 }
96 #endif
97