xref: /llvm-project/clang/test/Analysis/array-struct-region.cpp (revision d9b0268401840e1ad82df65af288e5a0a63da120)
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 #if __cplusplus
56   // FIXME: Passing the struct by value seems to be confusing C++.
57   // Possibly related to <rdar://problem/12137950>.
58   // expected-warning@-4{{UNKNOWN}}
59 #endif
60 
61   clang_analyzer_eval(getAssignedField(getS()) == 42); // expected-warning{{TRUE}}
62 }
63 
64 
65 //--------------------
66 // C++-only tests
67 //--------------------
68 
69 #if __cplusplus
70 void testReferenceAssignment() {
71   const S &s = getS();
72 
73   if (s.field != 42) return;
74   clang_analyzer_eval(s.field == 42); // expected-warning{{TRUE}}
75 
76   clang_analyzer_eval(s.getThis() == &s); // expected-warning{{TRUE}}
77 }
78 
79 
80 int getConstrainedFieldRef(const S &s) {
81   if (s.field != 42) return 42;
82   return s.field;
83 }
84 
85 bool checkThis(const S &s) {
86   return s.getThis() == &s;
87 }
88 
89 void testReferenceArgument() {
90   clang_analyzer_eval(getConstrainedFieldRef(getS()) == 42); // expected-warning{{TRUE}}
91   clang_analyzer_eval(checkThis(getS())); // expected-warning{{TRUE}}
92 }
93 #endif
94