Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / clang / test / Analysis / operator-calls.cpp
blob64abda150c5a14470e97d68f1fdc365782682798
1 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-output=text -verify %s
2 void clang_analyzer_eval(bool);
4 struct X0 { };
5 bool operator==(const X0&, const X0&);
7 // PR7287
8 struct test { int a[2]; };
10 void t2() {
11 test p = {{1,2}};
12 test q;
13 q = p;
16 bool PR7287(X0 a, X0 b) {
17 return operator==(a, b);
21 // Inlining non-static member operators mistakenly treated 'this' as the first
22 // argument for a while.
24 struct IntComparable {
25 bool operator==(int x) const {
26 return x == 0;
30 void testMemberOperator(IntComparable B) {
31 clang_analyzer_eval(B == 0); // expected-warning{{TRUE}}
32 // expected-note@-1{{TRUE}}
37 namespace UserDefinedConversions {
38 class Convertible {
39 public:
40 operator int() const {
41 return 42;
43 operator bool() const {
44 return true;
48 void test(const Convertible &obj) {
49 clang_analyzer_eval((int)obj == 42); // expected-warning{{TRUE}}
50 // expected-note@-1{{TRUE}}
51 clang_analyzer_eval(obj); // expected-warning{{TRUE}}
52 // expected-note@-1{{TRUE}}
57 namespace RValues {
58 struct SmallOpaque {
59 float x;
60 int operator +() const {
61 return (int)x;
65 struct LargeOpaque {
66 float x[4];
67 int operator +() const {
68 return (int)x[0];
72 SmallOpaque getSmallOpaque() {
73 SmallOpaque obj;
74 obj.x = 1.0;
75 return obj;
78 LargeOpaque getLargeOpaque() {
79 LargeOpaque obj = LargeOpaque();
80 obj.x[0] = 1.0;
81 return obj;
84 void test(int coin) {
85 // Force a cache-out when we try to conjure a temporary region for the operator call.
86 // ...then, don't crash.
87 clang_analyzer_eval(+(coin ? getSmallOpaque() : getSmallOpaque())); // expected-warning{{UNKNOWN}}
88 // expected-note@-1{{Assuming 'coin' is 0}}
89 // expected-note@-2{{'?' condition is false}}
90 // expected-note@-3{{UNKNOWN}}
91 // expected-note@-4{{Assuming 'coin' is 0}}
92 // expected-note@-5{{'?' condition is false}}
93 clang_analyzer_eval(+(coin ? getLargeOpaque() : getLargeOpaque())); // expected-warning{{UNKNOWN}}
94 // expected-note@-1{{'coin' is 0}}
95 // expected-note@-2{{'?' condition is false}}
96 // expected-note@-3{{UNKNOWN}}
100 namespace SynthesizedAssignment {
101 struct A {
102 int a;
103 A& operator=(A& other) { a = -other.a; return *this; }
104 A& operator=(A&& other) { a = other.a+1; return *this; }
107 struct B {
108 int x;
109 A a[3];
110 B& operator=(B&) = default;
111 B& operator=(B&&) = default;
114 // This used to produce a warning about the iteration variable in the
115 // synthesized assignment operator being undefined.
117 // Note: The warning we want to avoid can be found in https://bugs.llvm.org/show_bug.cgi?id=16745.
118 // Back in the day, this function was created we couldn't evaluate non-POD type array construction,
119 // so we couldn't evaluate the copy assignment either, hence we didn't detect that a field is
120 // uninitialized.
121 void testNoWarning() {
123 B v, u;
124 u = v; // expected-warning@110{{Assigned value is garbage or undefined}}
125 // expected-note@-1{{Calling defaulted copy assignment operator for 'B'}}
126 // expected-note@110{{Assigned value is garbage or undefined}}
129 void testNoWarningMove() {
130 B v, u;
131 u = static_cast<B &&>(v); // expected-warning@111{{Assigned value is garbage or undefined}}
132 // expected-note@-1{{Calling defaulted move assignment operator for 'B'}}
133 // expected-note@111{{Assigned value is garbage or undefined}}
136 void testConsistency() {
137 B v, u;
138 v.x = 0;
139 v.a[0].a = 24;
140 v.a[1].a = 47;
141 v.a[2].a = 42;
142 u = v;
143 clang_analyzer_eval(u.a[0].a == -24); // expected-warning{{TRUE}}
144 // expected-note@-1{{TRUE}}
145 clang_analyzer_eval(u.a[1].a == -47); // expected-warning{{TRUE}}
146 // expected-note@-1{{TRUE}}
147 clang_analyzer_eval(u.a[2].a == -42); // expected-warning{{TRUE}}
148 // expected-note@-1{{TRUE}}
151 void testConsistencyMove() {
152 B v, u;
153 v.x = 0;
154 v.a[0].a = 24;
155 v.a[1].a = 47;
156 v.a[2].a = 42;
157 u = static_cast<B &&>(v);
158 clang_analyzer_eval(u.a[0].a == 25); // expected-warning{{TRUE}}
159 // expected-note@-1{{TRUE}}
160 clang_analyzer_eval(u.a[1].a == 48); // expected-warning{{TRUE}}
161 // expected-note@-1{{TRUE}}
162 clang_analyzer_eval(u.a[2].a == 43); // expected-warning{{TRUE}}
163 // expected-note@-1{{TRUE}}