Home | History | Annotate | Download | only in SemaCXX
      1 // RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %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->'}}
    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(); // expected-note{{possible target for call}}
    391     int i(int); // expected-note{{possible target for call}}
    392   };
    393 
    394   struct Y {
    395     Y &operator<<(int);
    396   };
    397 
    398   void f(X x, Y y) {
    399     y << x
    400       .i; // expected-error{{reference to non-static member function must be called; did you mean to call it with no arguments?}}
    401   }
    402 }
    403 
    404 namespace rdar9222009 {
    405 class StringRef {
    406   inline bool operator==(StringRef LHS, StringRef RHS) { // expected-error{{overloaded 'operator==' must be a binary operator (has 3 parameters)}}
    407     return !(LHS == RHS); // expected-error{{invalid operands to binary expression ('rdar9222009::StringRef' and 'rdar9222009::StringRef')}}
    408   }
    409 };
    410 
    411 }
    412 
    413 namespace PR11784 {
    414   struct A { A& operator=(void (*x)()); };
    415   void f();
    416   void f(int);
    417   void g() { A x; x = f; }
    418 }
    419 
    420 namespace test10 {
    421   struct A {
    422     void operator[](float (*fn)(int)); // expected-note 2 {{not viable: no overload of 'bar' matching 'float (*)(int)'}}
    423   };
    424 
    425   float foo(int);
    426   float foo(float);
    427 
    428   template <class T> T bar(T);
    429   template <class T, class U> T bar(U);
    430 
    431   void test(A &a) {
    432     a[&foo];
    433     a[foo];
    434 
    435     a[&bar<int>]; // expected-error {{no viable overloaded operator[]}}
    436     a[bar<int>]; // expected-error {{no viable overloaded operator[]}}
    437 
    438     // If these fail, it's because we're not letting the overload
    439     // resolution for operator| resolve the overload of 'bar'.
    440     a[&bar<float>];
    441     a[bar<float>];
    442   }
    443 }
    444 
    445 struct InvalidOperatorEquals {
    446   InvalidOperatorEquals operator=() = delete; // expected-error {{overloaded 'operator=' must be a binary operator}}
    447 };
    448 
    449 namespace PR7681 {
    450   template <typename PT1, typename PT2> class PointerUnion;
    451   void foo(PointerUnion<int*, float*> &Result) {
    452     Result = 1; // expected-error {{no viable overloaded '='}} // expected-note {{type 'PointerUnion<int *, float *>' is incomplete}}
    453   }
    454 }
    455 
    456 namespace PR14995 {
    457   struct B {};
    458   template<typename ...T> void operator++(B, T...) {}
    459 
    460   void f() {
    461     B b;
    462     b++;  // ok
    463     ++b;  // ok
    464   }
    465 
    466   template<typename... T>
    467   struct C {
    468     void operator-- (T...) {}
    469   };
    470 
    471   void g() {
    472     C<int> postfix;
    473     C<> prefix;
    474     postfix--;  // ok
    475     --prefix;  // ok
    476   }
    477 
    478   struct D {};
    479   template<typename T> void operator++(D, T) {}
    480 
    481   void h() {
    482     D d;
    483     d++;  // ok
    484     ++d; // expected-error{{cannot increment value of type 'PR14995::D'}}
    485   }
    486 
    487   template<typename...T> struct E {
    488     void operator++(T...) {} // expected-error{{parameter of overloaded post-increment operator must have type 'int' (not 'char')}}
    489   };
    490 
    491   E<char> e; // expected-note {{in instantiation of template class 'PR14995::E<char>' requested here}}
    492 
    493   struct F {
    494     template<typename... T>
    495     int operator++ (T...) {}
    496   };
    497 
    498   int k1 = F().operator++(0, 0);
    499   int k2 = F().operator++('0');
    500   // expected-error@-5 {{overloaded 'operator++' must be a unary or binary operator}}
    501   // expected-note@-3 {{in instantiation of function template specialization 'PR14995::F::operator++<int, int>' requested here}}
    502   // expected-error@-4 {{no matching member function for call to 'operator++'}}
    503   // expected-note@-8 {{candidate template ignored: substitution failure}}
    504   // expected-error@-9 {{parameter of overloaded post-increment operator must have type 'int' (not 'char')}}
    505   // expected-note@-6 {{in instantiation of function template specialization 'PR14995::F::operator++<char>' requested here}}
    506   // expected-error@-7 {{no matching member function for call to 'operator++'}}
    507   // expected-note@-12 {{candidate template ignored: substitution failure}}
    508 } // namespace PR14995
    509 
    510 namespace ConversionVersusTemplateOrdering {
    511   struct A {
    512     operator short() = delete;
    513     template <typename T> operator T();
    514   } a;
    515   struct B {
    516     template <typename T> operator T();
    517     operator short() = delete;
    518   } b;
    519   int x = a;
    520   int y = b;
    521 }
    522 
    523 namespace NoADLForMemberOnlyOperators {
    524   template<typename T> struct A { typename T::error e; }; // expected-error {{type 'char' cannot be used prior to '::'}}
    525   template<typename T> struct B { int n; };
    526 
    527   void f(B<A<void> > b1, B<A<int> > b2, B<A<char> > b3) {
    528     b1 = b1; // ok, does not instantiate A<void>.
    529     (void)b1->n; // expected-error {{is not a pointer}}
    530     b2[3]; // expected-error {{does not provide a subscript}}
    531     b3 / 0; // expected-note {{in instantiation of}} expected-error {{invalid operands to}}
    532   }
    533 }
    534