summaryrefslogtreecommitdiff
path: root/clang/test/SemaCXX/overloaded-builtin-operators.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/SemaCXX/overloaded-builtin-operators.cpp')
-rw-r--r--clang/test/SemaCXX/overloaded-builtin-operators.cpp239
1 files changed, 239 insertions, 0 deletions
diff --git a/clang/test/SemaCXX/overloaded-builtin-operators.cpp b/clang/test/SemaCXX/overloaded-builtin-operators.cpp
new file mode 100644
index 0000000..b3c0808
--- /dev/null
+++ b/clang/test/SemaCXX/overloaded-builtin-operators.cpp
@@ -0,0 +1,239 @@
+// RUN: %clang_cc1 -fsyntax-only -fshow-overloads=best -verify %s
+struct yes;
+struct no;
+
+struct Short {
+ operator short();
+};
+
+struct Long {
+ operator long();
+};
+
+enum E1 { };
+struct Enum1 {
+ operator E1();
+};
+
+enum E2 { };
+struct Enum2 {
+ operator E2();
+};
+
+
+struct X {
+ void f();
+};
+
+typedef void (X::*pmf)();
+struct Xpmf {
+ operator pmf();
+};
+
+yes& islong(long);
+yes& islong(unsigned long); // FIXME: shouldn't be needed
+no& islong(int);
+
+void f(Short s, Long l, Enum1 e1, Enum2 e2, Xpmf pmf) {
+ // C++ [over.built]p8
+ int i1 = +e1;
+ int i2 = -e2;
+
+ // C++ [over.built]p10:
+ int i3 = ~s;
+ bool b1 = !s;
+
+ // C++ [over.built]p12
+ (void)static_cast<yes&>(islong(s + l));
+ (void)static_cast<no&>(islong(s + s));
+
+ // C++ [over.built]p16
+ (void)(pmf == &X::f);
+ (void)(pmf == 0);
+
+ // C++ [over.built]p17
+ (void)static_cast<yes&>(islong(s % l));
+ (void)static_cast<yes&>(islong(l << s));
+ (void)static_cast<no&>(islong(s << l));
+ (void)static_cast<yes&>(islong(e1 % l));
+ // FIXME: should pass (void)static_cast<no&>(islong(e1 % e2));
+}
+
+struct ShortRef { // expected-note{{candidate function (the implicit copy assignment operator)}}
+ operator short&();
+};
+
+struct LongRef {
+ operator volatile long&();
+};
+
+struct XpmfRef { // expected-note{{candidate function (the implicit copy assignment operator)}}
+ operator pmf&();
+};
+
+struct E2Ref {
+ operator E2&();
+};
+
+void g(ShortRef sr, LongRef lr, E2Ref e2_ref, XpmfRef pmf_ref) {
+ // C++ [over.built]p3
+ short s1 = sr++;
+
+ // C++ [over.built]p3
+ long l1 = lr--;
+
+ // C++ [over.built]p18
+ short& sr1 = (sr *= lr);
+ volatile long& lr1 = (lr *= sr);
+
+ // C++ [over.built]p20:
+ E2 e2r2;
+ e2r2 = e2_ref;
+
+ pmf &pmr = (pmf_ref = &X::f); // expected-error{{no viable overloaded '='}}
+ pmf pmr2;
+ pmr2 = pmf_ref;
+
+ // C++ [over.built]p22
+ short& sr2 = (sr %= lr);
+ volatile long& lr2 = (lr <<= sr);
+
+ bool b1 = (sr && lr) || (sr || lr);
+}
+
+struct VolatileIntPtr {
+ operator int volatile *();
+};
+
+struct ConstIntPtr {
+ operator int const *();
+};
+
+struct VolatileIntPtrRef {
+ operator int volatile *&();
+};
+
+struct ConstIntPtrRef {
+ operator int const *&();
+};
+
+void test_with_ptrs(VolatileIntPtr vip, ConstIntPtr cip, ShortRef sr,
+ VolatileIntPtrRef vipr, ConstIntPtrRef cipr) {
+ const int& cir1 = cip[sr];
+ const int& cir2 = sr[cip];
+ volatile int& vir1 = vip[sr];
+ volatile int& vir2 = sr[vip];
+ bool b1 = (vip == cip);
+ long p1 = vip - cip;
+
+ // C++ [over.built]p5:
+ int volatile *vip1 = vipr++;
+ int const *cip1 = cipr++;
+ int volatile *&vipr1 = ++vipr;
+ int const *&cipr1 = --cipr;
+
+ // C++ [over.built]p6:
+ int volatile &ivr = *vip;
+
+ // C++ [over.built]p8:
+ int volatile *vip2 = +vip;
+ int i1 = +sr;
+ int i2 = -sr;
+
+ // C++ [over.built]p13:
+ int volatile &ivr2 = vip[17];
+ int const &icr2 = 17[cip];
+}
+
+// C++ [over.match.open]p4
+
+void test_assign_restrictions(ShortRef& sr) {
+ sr = (short)0; // expected-error{{no viable overloaded '='}}
+}
+
+struct Base { };
+struct Derived1 : Base { };
+struct Derived2 : Base { };
+
+template<typename T>
+struct ConvertibleToPtrOf {
+ operator T*();
+};
+
+bool test_with_base_ptrs(ConvertibleToPtrOf<Derived1> d1,
+ ConvertibleToPtrOf<Derived2> d2) {
+ return d1 == d2; // expected-error{{invalid operands}}
+}
+
+// DR425
+struct A {
+ template< typename T > operator T() const;
+};
+
+void test_dr425(A a) {
+ // FIXME: lots of candidates here!
+ (void)(1.0f * a); // expected-error{{ambiguous}} \
+ // expected-note 4{{candidate}} \
+ // expected-note {{remaining 77 candidates omitted; pass -fshow-overloads=all to show them}}
+}
+
+// pr5432
+enum e {X};
+
+const int a[][2] = {{1}};
+
+int test_pr5432() {
+ return a[X][X];
+}
+
+void f() {
+ (void)__extension__(A());
+}
+
+namespace PR7319 {
+ typedef enum { Enum1, Enum2, Enum3 } MyEnum;
+
+ template<typename X> bool operator>(const X &inX1, const X &inX2);
+
+ void f() {
+ MyEnum e1, e2;
+ if (e1 > e2) {}
+ }
+}
+
+namespace PR8477 {
+ struct Foo {
+ operator bool();
+ operator const char *();
+ };
+
+ bool doit() {
+ Foo foo;
+ long long zero = 0;
+ (void)(foo + zero);
+ (void)(foo - zero);
+ (void)(zero + foo);
+ (void)(zero[foo]);
+ (void)(foo - foo); // expected-error{{use of overloaded operator '-' is ambiguous}} \
+ // expected-note 4{{built-in candidate operator-}} \
+ // expected-note{{candidates omitted}}
+ return foo[zero] == zero;
+ }
+}
+
+namespace PR7851 {
+ struct X {
+ operator const void *() const;
+ operator void *();
+
+ operator const unsigned *() const;
+ operator unsigned *();
+ };
+
+ void f() {
+ X x;
+ x[0] = 1;
+ *x = 0;
+ (void)(x - x);
+ }
+}