2009-03-24 10:24:46 +08:00
|
|
|
// RUN: clang-cc -fsyntax-only -verify %s
|
2008-11-08 04:08:42 +08:00
|
|
|
class X {
|
|
|
|
public:
|
|
|
|
operator bool();
|
|
|
|
operator int() const;
|
2008-11-18 04:34:05 +08:00
|
|
|
|
|
|
|
bool f() {
|
|
|
|
return operator bool();
|
|
|
|
}
|
|
|
|
|
|
|
|
float g() {
|
2009-02-04 23:01:18 +08:00
|
|
|
return operator float(); // expected-error{{no matching function for call to 'operator float'}}
|
2008-11-18 04:34:05 +08:00
|
|
|
}
|
2008-11-08 04:08:42 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
operator int(); // expected-error{{conversion function must be a non-static member function}}
|
|
|
|
|
2008-11-18 06:58:34 +08:00
|
|
|
operator int; // expected-error{{'operator int' cannot be the name of a variable or data member}}
|
|
|
|
|
2008-11-08 04:08:42 +08:00
|
|
|
typedef int func_type(int);
|
|
|
|
typedef int array_type[10];
|
|
|
|
|
|
|
|
class Y {
|
|
|
|
public:
|
|
|
|
void operator bool(int, ...) const; // expected-error{{conversion function cannot have a return type}} \
|
2009-04-25 16:35:12 +08:00
|
|
|
// expected-error{{conversion function cannot have any parameters}}
|
|
|
|
|
|
|
|
operator float(...) const; // expected-error{{conversion function cannot be variadic}}
|
|
|
|
|
|
|
|
|
2008-11-08 04:08:42 +08:00
|
|
|
operator func_type(); // expected-error{{conversion function cannot convert to a function type}}
|
|
|
|
operator array_type(); // expected-error{{conversion function cannot convert to an array type}}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
typedef int INT;
|
|
|
|
typedef INT* INT_PTR;
|
|
|
|
|
|
|
|
class Z {
|
2008-11-24 07:12:31 +08:00
|
|
|
operator int(); // expected-note {{previous declaration is here}}
|
|
|
|
operator int**(); // expected-note {{previous declaration is here}}
|
2008-11-08 04:08:42 +08:00
|
|
|
|
|
|
|
operator INT(); // expected-error{{conversion function cannot be redeclared}}
|
|
|
|
operator INT_PTR*(); // expected-error{{conversion function cannot be redeclared}}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
class A { };
|
|
|
|
|
|
|
|
class B : public A {
|
|
|
|
public:
|
|
|
|
operator A&() const; // expected-warning{{conversion function converting 'class B' to its base class 'class A' will never be used}}
|
|
|
|
operator const void() const; // expected-warning{{conversion function converting 'class B' to 'void const' will never be used}}
|
|
|
|
operator const B(); // expected-warning{{conversion function converting 'class B' to itself will never be used}}
|
|
|
|
};
|
2009-04-17 01:51:27 +08:00
|
|
|
|
|
|
|
// This used to crash Clang.
|
|
|
|
struct Flip;
|
|
|
|
struct Flop {
|
|
|
|
Flop();
|
|
|
|
Flop(const Flip&);
|
|
|
|
};
|
|
|
|
struct Flip {
|
|
|
|
operator Flop() const;
|
|
|
|
};
|
|
|
|
Flop flop = Flip(); // expected-error {{cannot initialize 'flop' with an rvalue of type 'struct Flip'}}
|
2009-09-14 05:33:06 +08:00
|
|
|
|
|
|
|
// This tests that we don't add the second conversion declaration to the list of user conversions
|
|
|
|
struct C {
|
|
|
|
operator const char *() const;
|
|
|
|
};
|
|
|
|
|
|
|
|
C::operator const char*() const { return 0; }
|
|
|
|
|
|
|
|
void f(const C& c) {
|
|
|
|
const char* v = c;
|
|
|
|
}
|
2009-09-15 04:41:01 +08:00
|
|
|
|
|
|
|
// Test. Conversion in base class is visible in derived class.
|
|
|
|
class XB {
|
|
|
|
public:
|
2009-09-15 08:10:11 +08:00
|
|
|
operator int(); // expected-note {{candidate function}}
|
2009-09-15 04:41:01 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
class Yb : public XB {
|
|
|
|
public:
|
2009-09-15 08:10:11 +08:00
|
|
|
operator char(); // expected-note {{candidate function}}
|
2009-09-15 04:41:01 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
void f(Yb& a) {
|
2009-09-15 08:10:11 +08:00
|
|
|
if (a) { } // expected-error {{conversion from 'class Yb' to 'bool' is ambiguous}}
|
2009-09-15 04:41:01 +08:00
|
|
|
int i = a; // OK. calls XB::operator int();
|
|
|
|
char ch = a; // OK. calls Yb::operator char();
|
|
|
|
}
|
|
|
|
|