Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify %s
      2 class X { };
      3 
      4 X operator+(X, X);
      5 
      6 void f(X x) {
      7   x = x + x;
      8 }
      9 
     10 struct Y;
     11 struct Z;
     12 
     13 struct Y {
     14   Y(const Z&);
     15 };
     16 
     17 struct Z {
     18   Z(const Y&);
     19 };
     20 
     21 Y operator+(Y, Y);
     22 bool operator-(Y, Y); // expected-note{{candidate function}}
     23 bool operator-(Z, Z); // expected-note{{candidate function}}
     24 
     25 void g(Y y, Z z) {
     26   y = y + z;
     27   bool b = y - z; // expected-error{{use of overloaded operator '-' is ambiguous}}
     28 }
     29 
     30 struct A {
     31   bool operator==(Z&); // expected-note 2{{candidate function}}
     32 };
     33 
     34 A make_A();
     35 
     36 bool operator==(A&, Z&); // expected-note 3{{candidate function}}
     37 
     38 void h(A a, const A ac, Z z) {
     39   make_A() == z; // expected-warning{{equality comparison result unused}}
     40   a == z; // expected-error{{use of overloaded operator '==' is ambiguous}}
     41   ac == z; // expected-error{{invalid operands to binary expression ('const A' and 'Z')}}
     42 }
     43 
     44 struct B {
     45   bool operator==(const B&) const;
     46 
     47   void test(Z z) {
     48     make_A() == z; // expected-warning{{equality comparison result unused}}
     49   }
     50 };
     51 
     52 // we shouldn't see warnings about self-comparison,
     53 // this is a member function, we dunno what it'll do
     54 bool i(B b)
     55 {
     56   return b == b;
     57 }
     58 
     59 enum Enum1 { };
     60 enum Enum2 { };
     61 
     62 struct E1 {
     63   E1(Enum1) { }
     64 };
     65 
     66 struct E2 {
     67   E2(Enum2);
     68 };
     69 
     70 // C++ [over.match.oper]p3 - enum restriction.
     71 float& operator==(E1, E2);  // expected-note{{candidate function}}
     72 
     73 void enum_test(Enum1 enum1, Enum2 enum2, E1 e1, E2 e2, Enum1 next_enum1) {
     74   float &f1 = (e1 == e2);
     75   float &f2 = (enum1 == e2);
     76   float &f3 = (e1 == enum2);
     77   float &f4 = (enum1 == next_enum1);  // expected-error{{non-const lvalue reference to type 'float' cannot bind to a temporary of type 'bool'}}
     78 }
     79 
     80 // PR5244 - Argument-dependent lookup would include the two operators below,
     81 // which would break later assumptions and lead to a crash.
     82 class pr5244_foo
     83 {
     84   pr5244_foo(int);
     85   pr5244_foo(char);
     86 };
     87 
     88 bool operator==(const pr5244_foo& s1, const pr5244_foo& s2); // expected-note{{candidate function}}
     89 bool operator==(char c, const pr5244_foo& s); // expected-note{{candidate function}}
     90 
     91 enum pr5244_bar
     92 {
     93     pr5244_BAR
     94 };
     95 
     96 class pr5244_baz
     97 {
     98 public:
     99     pr5244_bar quux;
    100 };
    101 
    102 void pr5244_barbaz()
    103 {
    104   pr5244_baz quuux;
    105   (void)(pr5244_BAR == quuux.quux);
    106 }
    107 
    108 
    109 
    110 struct PostInc {
    111   PostInc operator++(int);
    112   PostInc& operator++();
    113 };
    114 
    115 struct PostDec {
    116   PostDec operator--(int);
    117   PostDec& operator--();
    118 };
    119 
    120 void incdec_test(PostInc pi, PostDec pd) {
    121   const PostInc& pi1 = pi++;
    122   const PostDec& pd1 = pd--;
    123   PostInc &pi2 = ++pi;
    124   PostDec &pd2 = --pd;
    125 }
    126 
    127 struct SmartPtr {
    128   int& operator*();
    129   long& operator*() const volatile;
    130 };
    131 
    132 void test_smartptr(SmartPtr ptr, const SmartPtr cptr,
    133                    const volatile SmartPtr cvptr) {
    134   int &ir = *ptr;
    135   long &lr = *cptr;
    136   long &lr2 = *cvptr;
    137 }
    138 
    139 
    140 struct ArrayLike {
    141   int& operator[](int);
    142 };
    143 
    144 void test_arraylike(ArrayLike a) {
    145   int& ir = a[17];
    146 }
    147 
    148 struct SmartRef {
    149   int* operator&();
    150 };
    151 
    152 void test_smartref(SmartRef r) {
    153   int* ip = &r;
    154 }
    155 
    156 bool& operator,(X, Y);
    157 
    158 void test_comma(X x, Y y) {
    159   bool& b1 = (x, y);
    160   X& xr = (x, x); // expected-warning {{expression result unused}}
    161 }
    162 
    163 struct Callable {
    164   int& operator()(int, double = 2.71828); // expected-note{{candidate function}}
    165   float& operator()(int, double, long, ...); // expected-note{{candidate function}}
    166 
    167   double& operator()(float); // expected-note{{candidate function}}
    168 };
    169 
    170 struct Callable2 {
    171   int& operator()(int i = 0);
    172   double& operator()(...) const;
    173 };
    174 
    175 struct DerivesCallable : public Callable {
    176 };
    177 
    178 void test_callable(Callable c, Callable2 c2, const Callable2& c2c,
    179                    DerivesCallable dc) {
    180   int &ir = c(1);
    181   float &fr = c(1, 3.14159, 17, 42);
    182 
    183   c(); // expected-error{{no matching function for call to object of type 'Callable'}}
    184 
    185   double &dr = c(1.0f);
    186 
    187   int &ir2 = c2();
    188   int &ir3 = c2(1);
    189   double &fr2 = c2c();
    190 
    191   int &ir4 = dc(17);
    192   double &fr3 = dc(3.14159f);
    193 }
    194 
    195 typedef float FLOAT;
    196 typedef int& INTREF;
    197 typedef INTREF Func1(FLOAT, double);
    198 typedef float& Func2(int, double);
    199 
    200 struct ConvertToFunc {
    201   operator Func1*(); // expected-note 2{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}}
    202   operator Func2&(); // expected-note 2{{conversion candidate of type 'float &(&)(int, double)'}}
    203   void operator()();
    204 };
    205 
    206 struct ConvertToFuncDerived : ConvertToFunc { };
    207 
    208 void test_funcptr_call(ConvertToFunc ctf, ConvertToFuncDerived ctfd) {
    209   int &i1 = ctf(1.0f, 2.0);
    210   float &f1 = ctf((short int)1, 1.0f);
    211   ctf((long int)17, 2.0); // expected-error{{call to object of type 'ConvertToFunc' is ambiguous}}
    212   ctf();
    213 
    214   int &i2 = ctfd(1.0f, 2.0);
    215   float &f2 = ctfd((short int)1, 1.0f);
    216   ctfd((long int)17, 2.0); // expected-error{{call to object of type 'ConvertToFuncDerived' is ambiguous}}
    217   ctfd();
    218 }
    219 
    220 struct HasMember {
    221   int m;
    222 };
    223 
    224 struct Arrow1 {
    225   HasMember* operator->();
    226 };
    227 
    228 struct Arrow2 {
    229   Arrow1 operator->(); // expected-note{{candidate function}}
    230 };
    231 
    232 void test_arrow(Arrow1 a1, Arrow2 a2, const Arrow2 a3) {
    233   int &i1 = a1->m;
    234   int &i2 = a2->m;
    235   a3->m; // expected-error{{no viable overloaded 'operator->'; candidate is}}
    236 }
    237 
    238 struct CopyConBase {
    239 };
    240 
    241 struct CopyCon : public CopyConBase {
    242   CopyCon(const CopyConBase &Base);
    243 
    244   CopyCon(const CopyConBase *Base) {
    245     *this = *Base;
    246   }
    247 };
    248 
    249 namespace N {
    250   struct X { };
    251 }
    252 
    253 namespace M {
    254   N::X operator+(N::X, N::X);
    255 }
    256 
    257 namespace M {
    258   void test_X(N::X x) {
    259     (void)(x + x);
    260   }
    261 }
    262 
    263 struct AA { bool operator!=(AA&); };
    264 struct BB : AA {};
    265 bool x(BB y, BB z) { return y != z; }
    266 
    267 
    268 struct AX {
    269   AX& operator ->();	 // expected-note {{declared here}}
    270   int b;
    271 };
    272 
    273 void m() {
    274   AX a;
    275   a->b = 0; // expected-error {{circular pointer delegation detected}}
    276 }
    277 
    278 struct CircA {
    279   struct CircB& operator->(); // expected-note {{declared here}}
    280   int val;
    281 };
    282 struct CircB {
    283   struct CircC& operator->(); // expected-note {{declared here}}
    284 };
    285 struct CircC {
    286   struct CircA& operator->(); // expected-note {{declared here}}
    287 };
    288 
    289 void circ() {
    290   CircA a;
    291   a->val = 0; // expected-error {{circular pointer delegation detected}}
    292 }
    293 
    294 // PR5360: Arrays should lead to built-in candidates for subscript.
    295 typedef enum {
    296   LastReg = 23,
    297 } Register;
    298 class RegAlloc {
    299   int getPriority(Register r) {
    300     return usepri[r];
    301   }
    302   int usepri[LastReg + 1];
    303 };
    304 
    305 // PR5546: Don't generate incorrect and ambiguous overloads for multi-level
    306 // arrays.
    307 namespace pr5546
    308 {
    309   enum { X };
    310   extern const char *const sMoveCommands[][2][2];
    311   const char* a() { return sMoveCommands[X][0][0]; }
    312   const char* b() { return (*(sMoveCommands+X))[0][0]; }
    313 }
    314 
    315 // PR5512 and its discussion
    316 namespace pr5512 {
    317   struct Y {
    318     operator short();
    319     operator float();
    320   };
    321   void g_test(Y y) {
    322     short s = 0;
    323     // DR507, this should be ambiguous, but we special-case assignment
    324     s = y;
    325     // Note: DR507, this is ambiguous as specified
    326     //s += y;
    327   }
    328 
    329   struct S {};
    330   void operator +=(int&, S);
    331   void f(S s) {
    332     int i = 0;
    333     i += s;
    334   }
    335 
    336   struct A {operator int();};
    337   int a;
    338   void b(A x) {
    339     a += x;
    340   }
    341 }
    342 
    343 // PR5900
    344 namespace pr5900 {
    345   struct NotAnArray {};
    346   void test0() {
    347     NotAnArray x;
    348     x[0] = 0; // expected-error {{does not provide a subscript operator}}
    349   }
    350 
    351   struct NonConstArray {
    352     int operator[](unsigned); // expected-note {{candidate}}
    353   };
    354   int test1() {
    355     const NonConstArray x = NonConstArray();
    356     return x[0]; // expected-error {{no viable overloaded operator[] for type}}
    357   }
    358 
    359   // Not really part of this PR, but implemented at the same time.
    360   struct NotAFunction {};
    361   void test2() {
    362     NotAFunction x;
    363     x(); // expected-error {{does not provide a call operator}}
    364   }
    365 }
    366 
    367 // Operator lookup through using declarations.
    368 namespace N {
    369   struct X2 { };
    370 }
    371 
    372 namespace N2 {
    373   namespace M {
    374     namespace Inner {
    375       template<typename T>
    376       N::X2 &operator<<(N::X2&, const T&);
    377     }
    378     using Inner::operator<<;
    379   }
    380 }
    381 
    382 void test_lookup_through_using() {
    383   using namespace N2::M;
    384   N::X2 x;
    385   x << 17;
    386 }
    387 
    388 namespace rdar9136502 {
    389   struct X {
    390     int i();
    391     int i(int);
    392   };
    393 
    394   struct Y {
    395     Y &operator<<(int);
    396   };
    397 
    398   void f(X x, Y y) {
    399     y << x.i; // expected-error{{reference to non-static member function must be called}}
    400   }
    401 }
    402 
    403 namespace rdar9222009 {
    404 class StringRef {
    405   inline bool operator==(StringRef LHS, StringRef RHS) { // expected-error{{overloaded 'operator==' must be a binary operator (has 3 parameters)}}
    406     return !(LHS == RHS); // expected-error{{invalid operands to binary expression ('rdar9222009::StringRef' and 'rdar9222009::StringRef')}}
    407   }
    408 };
    409 
    410 }
    411