166 lines · cpp
1// RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,alpha.core,debug.ExprInspection -analyzer-output=text -verify %s2void clang_analyzer_eval(bool);3 4struct X0 { };5bool operator==(const X0&, const X0&);6 7// PR72878struct test { int a[2]; };9 10void t2() {11 test p = {{1,2}};12 test q;13 q = p;14}15 16bool PR7287(X0 a, X0 b) {17 return operator==(a, b);18}19 20 21// Inlining non-static member operators mistakenly treated 'this' as the first22// argument for a while.23 24struct IntComparable {25 bool operator==(int x) const {26 return x == 0;27 }28};29 30void testMemberOperator(IntComparable B) {31 clang_analyzer_eval(B == 0); // expected-warning{{TRUE}}32 // expected-note@-1{{TRUE}}33}34 35 36 37namespace UserDefinedConversions {38 class Convertible {39 public:40 operator int() const {41 return 42;42 }43 operator bool() const {44 return true;45 }46 };47 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}}53 }54}55 56 57namespace RValues {58 struct SmallOpaque {59 float x;60 int operator +() const {61 return (int)x;62 }63 };64 65 struct LargeOpaque {66 float x[4];67 int operator +() const {68 return (int)x[0];69 }70 };71 72 SmallOpaque getSmallOpaque() {73 SmallOpaque obj;74 obj.x = 1.0;75 return obj;76 }77 78 LargeOpaque getLargeOpaque() {79 LargeOpaque obj = LargeOpaque();80 obj.x[0] = 1.0;81 return obj;82 }83 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}}97 }98}99 100namespace 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; }105 };106 107 struct B {108 int x;109 A a[3];110 B& operator=(B&) = default;111 B& operator=(B&&) = default;112 };113 114 // This used to produce a warning about the iteration variable in the115 // synthesized assignment operator being undefined.116 //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 is120 // uninitialized.121 void testNoWarning() {122 123 B v, u;124 u = v; // expected-warning@110{{Assigned value is uninitialized}}125 // expected-note@-1{{Calling defaulted copy assignment operator for 'B'}}126 // expected-note@110{{Assigned value is uninitialized}}127 }128 129 void testNoWarningMove() {130 B v, u;131 u = static_cast<B &&>(v); // expected-warning@111{{Assigned value is uninitialized}}132 // expected-note@-1{{Calling defaulted move assignment operator for 'B'}}133 // expected-note@111{{Assigned value is uninitialized}}134 }135 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}}149 }150 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}}164 }165}166