/extern/llvm/tools/clang/test/SemaCXX/overloaded-operator.cpp
C++ | 417 lines | 316 code | 85 blank | 16 comment | 12 complexity | 8bd9ee255036448e9f200193291300d4 MD5 | raw file
Possible License(s): JSON, BSD-3-Clause
- // RUN: %clang_cc1 -fsyntax-only -verify %s
- class X { };
-
- X operator+(X, X);
-
- void f(X x) {
- x = x + x;
- }
-
- struct Y;
- struct Z;
-
- struct Y {
- Y(const Z&);
- };
-
- struct Z {
- Z(const Y&);
- };
-
- Y operator+(Y, Y);
- bool operator-(Y, Y); // expected-note{{candidate function}}
- bool operator-(Z, Z); // expected-note{{candidate function}}
-
- void g(Y y, Z z) {
- y = y + z;
- bool b = y - z; // expected-error{{use of overloaded operator '-' is ambiguous}}
- }
-
- struct A {
- bool operator==(Z&); // expected-note 2{{candidate function}}
- };
-
- A make_A();
-
- bool operator==(A&, Z&); // expected-note 3{{candidate function}}
-
- void h(A a, const A ac, Z z) {
- make_A() == z; // expected-warning{{equality comparison result unused}}
- a == z; // expected-error{{use of overloaded operator '==' is ambiguous}}
- ac == z; // expected-error{{invalid operands to binary expression ('const A' and 'Z')}}
- }
-
- struct B {
- bool operator==(const B&) const;
-
- void test(Z z) {
- make_A() == z; // expected-warning{{equality comparison result unused}}
- }
- };
-
- // we shouldn't see warnings about self-comparison,
- // this is a member function, we dunno what it'll do
- bool i(B b)
- {
- return b == b;
- }
-
- enum Enum1 { };
- enum Enum2 { };
-
- struct E1 {
- E1(Enum1) { }
- };
-
- struct E2 {
- E2(Enum2);
- };
-
- // C++ [over.match.oper]p3 - enum restriction.
- float& operator==(E1, E2); // expected-note{{candidate function}}
-
- void enum_test(Enum1 enum1, Enum2 enum2, E1 e1, E2 e2, Enum1 next_enum1) {
- float &f1 = (e1 == e2);
- float &f2 = (enum1 == e2);
- float &f3 = (e1 == enum2);
- float &f4 = (enum1 == next_enum1); // expected-error{{non-const lvalue reference to type 'float' cannot bind to a temporary of type 'bool'}}
- }
-
- // PR5244 - Argument-dependent lookup would include the two operators below,
- // which would break later assumptions and lead to a crash.
- class pr5244_foo
- {
- pr5244_foo(int);
- pr5244_foo(char);
- };
-
- bool operator==(const pr5244_foo& s1, const pr5244_foo& s2); // expected-note{{candidate function}}
- bool operator==(char c, const pr5244_foo& s); // expected-note{{candidate function}}
-
- enum pr5244_bar
- {
- pr5244_BAR
- };
-
- class pr5244_baz
- {
- public:
- pr5244_bar quux;
- };
-
- void pr5244_barbaz()
- {
- pr5244_baz quuux;
- (void)(pr5244_BAR == quuux.quux);
- }
-
-
-
- struct PostInc {
- PostInc operator++(int);
- PostInc& operator++();
- };
-
- struct PostDec {
- PostDec operator--(int);
- PostDec& operator--();
- };
-
- void incdec_test(PostInc pi, PostDec pd) {
- const PostInc& pi1 = pi++;
- const PostDec& pd1 = pd--;
- PostInc &pi2 = ++pi;
- PostDec &pd2 = --pd;
- }
-
- struct SmartPtr {
- int& operator*();
- long& operator*() const volatile;
- };
-
- void test_smartptr(SmartPtr ptr, const SmartPtr cptr,
- const volatile SmartPtr cvptr) {
- int &ir = *ptr;
- long &lr = *cptr;
- long &lr2 = *cvptr;
- }
-
-
- struct ArrayLike {
- int& operator[](int);
- };
-
- void test_arraylike(ArrayLike a) {
- int& ir = a[17];
- }
-
- struct SmartRef {
- int* operator&();
- };
-
- void test_smartref(SmartRef r) {
- int* ip = &r;
- }
-
- bool& operator,(X, Y);
-
- void test_comma(X x, Y y) {
- bool& b1 = (x, y);
- X& xr = (x, x); // expected-warning {{expression result unused}}
- }
-
- struct Callable {
- int& operator()(int, double = 2.71828); // expected-note{{candidate function}}
- float& operator()(int, double, long, ...); // expected-note{{candidate function}}
-
- double& operator()(float); // expected-note{{candidate function}}
- };
-
- struct Callable2 {
- int& operator()(int i = 0);
- double& operator()(...) const;
- };
-
- struct DerivesCallable : public Callable {
- };
-
- void test_callable(Callable c, Callable2 c2, const Callable2& c2c,
- DerivesCallable dc) {
- int &ir = c(1);
- float &fr = c(1, 3.14159, 17, 42);
-
- c(); // expected-error{{no matching function for call to object of type 'Callable'}}
-
- double &dr = c(1.0f);
-
- int &ir2 = c2();
- int &ir3 = c2(1);
- double &fr2 = c2c();
-
- int &ir4 = dc(17);
- double &fr3 = dc(3.14159f);
- }
-
- typedef float FLOAT;
- typedef int& INTREF;
- typedef INTREF Func1(FLOAT, double);
- typedef float& Func2(int, double);
-
- struct ConvertToFunc {
- operator Func1*(); // expected-note 2{{conversion candidate of type 'INTREF (*)(FLOAT, double)'}}
- operator Func2&(); // expected-note 2{{conversion candidate of type 'float &(&)(int, double)'}}
- void operator()();
- };
-
- struct ConvertToFuncDerived : ConvertToFunc { };
-
- void test_funcptr_call(ConvertToFunc ctf, ConvertToFuncDerived ctfd) {
- int &i1 = ctf(1.0f, 2.0);
- float &f1 = ctf((short int)1, 1.0f);
- ctf((long int)17, 2.0); // expected-error{{call to object of type 'ConvertToFunc' is ambiguous}}
- ctf();
-
- int &i2 = ctfd(1.0f, 2.0);
- float &f2 = ctfd((short int)1, 1.0f);
- ctfd((long int)17, 2.0); // expected-error{{call to object of type 'ConvertToFuncDerived' is ambiguous}}
- ctfd();
- }
-
- struct HasMember {
- int m;
- };
-
- struct Arrow1 {
- HasMember* operator->();
- };
-
- struct Arrow2 {
- Arrow1 operator->(); // expected-note{{candidate function}}
- };
-
- void test_arrow(Arrow1 a1, Arrow2 a2, const Arrow2 a3) {
- int &i1 = a1->m;
- int &i2 = a2->m;
- a3->m; // expected-error{{no viable overloaded 'operator->'}}
- }
-
- struct CopyConBase {
- };
-
- struct CopyCon : public CopyConBase {
- CopyCon(const CopyConBase &Base);
-
- CopyCon(const CopyConBase *Base) {
- *this = *Base;
- }
- };
-
- namespace N {
- struct X { };
- }
-
- namespace M {
- N::X operator+(N::X, N::X);
- }
-
- namespace M {
- void test_X(N::X x) {
- (void)(x + x);
- }
- }
-
- struct AA { bool operator!=(AA&); };
- struct BB : AA {};
- bool x(BB y, BB z) { return y != z; }
-
-
- struct AX {
- AX& operator ->(); // expected-note {{declared here}}
- int b;
- };
-
- void m() {
- AX a;
- a->b = 0; // expected-error {{circular pointer delegation detected}}
- }
-
- struct CircA {
- struct CircB& operator->(); // expected-note {{declared here}}
- int val;
- };
- struct CircB {
- struct CircC& operator->(); // expected-note {{declared here}}
- };
- struct CircC {
- struct CircA& operator->(); // expected-note {{declared here}}
- };
-
- void circ() {
- CircA a;
- a->val = 0; // expected-error {{circular pointer delegation detected}}
- }
-
- // PR5360: Arrays should lead to built-in candidates for subscript.
- typedef enum {
- LastReg = 23,
- } Register;
- class RegAlloc {
- int getPriority(Register r) {
- return usepri[r];
- }
- int usepri[LastReg + 1];
- };
-
- // PR5546: Don't generate incorrect and ambiguous overloads for multi-level
- // arrays.
- namespace pr5546
- {
- enum { X };
- extern const char *const sMoveCommands[][2][2];
- const char* a() { return sMoveCommands[X][0][0]; }
- const char* b() { return (*(sMoveCommands+X))[0][0]; }
- }
-
- // PR5512 and its discussion
- namespace pr5512 {
- struct Y {
- operator short();
- operator float();
- };
- void g_test(Y y) {
- short s = 0;
- // DR507, this should be ambiguous, but we special-case assignment
- s = y;
- // Note: DR507, this is ambiguous as specified
- //s += y;
- }
-
- struct S {};
- void operator +=(int&, S);
- void f(S s) {
- int i = 0;
- i += s;
- }
-
- struct A {operator int();};
- int a;
- void b(A x) {
- a += x;
- }
- }
-
- // PR5900
- namespace pr5900 {
- struct NotAnArray {};
- void test0() {
- NotAnArray x;
- x[0] = 0; // expected-error {{does not provide a subscript operator}}
- }
-
- struct NonConstArray {
- int operator[](unsigned); // expected-note {{candidate}}
- };
- int test1() {
- const NonConstArray x = NonConstArray();
- return x[0]; // expected-error {{no viable overloaded operator[] for type}}
- }
-
- // Not really part of this PR, but implemented at the same time.
- struct NotAFunction {};
- void test2() {
- NotAFunction x;
- x(); // expected-error {{does not provide a call operator}}
- }
- }
-
- // Operator lookup through using declarations.
- namespace N {
- struct X2 { };
- }
-
- namespace N2 {
- namespace M {
- namespace Inner {
- template<typename T>
- N::X2 &operator<<(N::X2&, const T&);
- }
- using Inner::operator<<;
- }
- }
-
- void test_lookup_through_using() {
- using namespace N2::M;
- N::X2 x;
- x << 17;
- }
-
- namespace rdar9136502 {
- struct X {
- int i();
- int i(int);
- };
-
- struct Y {
- Y &operator<<(int);
- };
-
- void f(X x, Y y) {
- y << x.i; // expected-error{{reference to non-static member function must be called}}
- }
- }
-
- namespace rdar9222009 {
- class StringRef {
- inline bool operator==(StringRef LHS, StringRef RHS) { // expected-error{{overloaded 'operator==' must be a binary operator (has 3 parameters)}}
- return !(LHS == RHS); // expected-error{{invalid operands to binary expression ('rdar9222009::StringRef' and 'rdar9222009::StringRef')}}
- }
- };
-
- }
-
- namespace PR11784 {
- struct A { A& operator=(void (*x)()); };
- void f();
- void f(int);
- void g() { A x; x = f; }
- }