1 // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify %s
2 void clang_analyzer_eval(bool);
3 
4 struct X0 { };
5 bool operator==(const X0&, const X0&);
6 
7 // PR7287
8 struct test { int a[2]; };
9 
10 void t2() {
11   test p = {{1,2}};
12   test q;
13   q = p;
14 }
15 
16 bool 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 
24 struct IntComparable {
25   bool operator==(int x) const {
26     return x == 0;
27   }
28 };
29 
30 void testMemberOperator(IntComparable B) {
31   clang_analyzer_eval(B == 0); // expected-warning{{TRUE}}
32 }
33 
34 
35 
36 namespace 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 
54 namespace 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