xref: /llvm-project/clang/test/Analysis/array-struct-region.cpp (revision 88dd13fdcacf9617437769b25da4be1588496f51)
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 
4 void clang_analyzer_eval(int);
5 
6 struct S {
7   int field;
8 
9 #if __cplusplus
10   const struct S *getThis() const { return this; }
11 #endif
12 };
13 
14 struct S getS();
15 
16 
17 void testAssignment() {
18   struct S s = getS();
19 
20   if (s.field != 42) return;
21   clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}}
22 
23   s.field = 0;
24   clang_analyzer_eval(s.field == 0); // expected-warning{{TRUE}}
25 
26 #if __cplusplus
27   clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}}
28 #endif
29 }
30 
31 
32 void testImmediateUse() {
33   int x = getS().field;
34 
35   if (x != 42) return;
36   clang_analyzer_eval(x == 42); // expected-warning{{TRUE}}
37 
38 #if __cplusplus
39   clang_analyzer_eval((void *)getS().getThis() == (void *)&x); // expected-warning{{FALSE}}
40 #endif
41 }
42 
43 int getConstrainedField(struct S s) {
44   if (s.field != 42) return 42;
45   return s.field;
46 }
47 
48 int getAssignedField(struct S s) {
49   s.field = 42;
50   return s.field;
51 }
52 
53 void testArgument() {
54   clang_analyzer_eval(getConstrainedField(getS()) == 42); // expected-warning{{TRUE}}
55   clang_analyzer_eval(getAssignedField(getS()) == 42); // expected-warning{{TRUE}}
56 }
57 
58 
59 //--------------------
60 // C++-only tests
61 //--------------------
62 
63 #if __cplusplus
64 void testReferenceAssignment() {
65   const S &s = getS();
66 
67   if (s.field != 42) return;
68   clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}}
69 
70   clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}}
71 }
72 
73 
74 int getConstrainedFieldRef(const S &s) {
75   if (s.field != 42) return 42;
76   return s.field;
77 }
78 
79 bool checkThis(const S &s) {
80   return s.getThis() == &s;
81 }
82 
83 void testReferenceArgument() {
84   clang_analyzer_eval(getConstrainedFieldRef(getS()) == 42); // expected-warning{{TRUE}}
85   clang_analyzer_eval(checkThis(getS())); // expected-warning{{TRUE}}
86 }
87 #endif
88