operator-calls.cpp revision 476f41c4750421a7ead5014e75a0e790ff682754
1// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify %s 2void clang_analyzer_eval(bool); 3 4struct X0 { }; 5bool operator==(const X0&, const X0&); 6 7// PR7287 8struct 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 first 22// 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} 33 34 35 36namespace UserDefinedConversions { 37 class Convertible { 38 public: 39 operator int() const { 40 return 42; 41 } 42 operator bool() const { 43 return true; 44 } 45 }; 46 47 void test(const Convertible &obj) { 48 clang_analyzer_eval((int)obj == 42); // expected-warning{{TRUE}} 49 clang_analyzer_eval(obj); // expected-warning{{TRUE}} 50 } 51} 52 53 54namespace RValues { 55 struct SmallOpaque { 56 float x; 57 int operator +() const { 58 return (int)x; 59 } 60 }; 61 62 struct LargeOpaque { 63 float x[4]; 64 int operator +() const { 65 return (int)x[0]; 66 } 67 }; 68 69 SmallOpaque getSmallOpaque() { 70 SmallOpaque obj; 71 obj.x = 1.0; 72 return obj; 73 } 74 75 LargeOpaque getLargeOpaque() { 76 LargeOpaque obj = LargeOpaque(); 77 obj.x[0] = 1.0; 78 return obj; 79 } 80 81 void test(int coin) { 82 // Force a cache-out when we try to conjure a temporary region for the operator call. 83 // ...then, don't crash. 84 clang_analyzer_eval(+(coin ? getSmallOpaque() : getSmallOpaque())); // expected-warning{{UNKNOWN}} 85 clang_analyzer_eval(+(coin ? getLargeOpaque() : getLargeOpaque())); // expected-warning{{UNKNOWN}} 86 } 87} 88