overloaded-builtin-operators.cpp revision 652371ad0427b2310ff01ea22fdc37f02d19abe8
1d7d5f0223bd30dfd618762349c6209dd1d5ea3e6Daniel Dunbar// RUN: clang-cc -fsyntax-only -verify %s
2eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregorstruct yes;
3eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregorstruct no;
4eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor
5eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregorstruct Short {
6eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  operator short();
7eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor};
8eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor
9eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregorstruct Long {
10eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  operator long();
11eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor};
12eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor
13447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregorenum E1 { };
14447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregorstruct Enum1 {
15447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor  operator E1();
16447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor};
17447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor
18447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregorenum E2 { };
19447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregorstruct Enum2 {
20447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor  operator E2();
21447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor};
22447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor
2320b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor
2420b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregorstruct X {
2520b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  void f();
2620b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor};
2720b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor
2820b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregortypedef void (X::*pmf)();
2920b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregorstruct Xpmf {
3020b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  operator pmf();
3120b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor};
3220b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor
33eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregoryes& islong(long);
34447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregoryes& islong(unsigned long); // FIXME: shouldn't be needed
35eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregorno& islong(int);
36eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor
3720b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregorvoid f(Short s, Long l, Enum1 e1, Enum2 e2, Xpmf pmf) {
3874253736184c0717a0649922551bf9d8b6815651Douglas Gregor  // C++ [over.built]p8
3974253736184c0717a0649922551bf9d8b6815651Douglas Gregor  int i1 = +e1;
4074253736184c0717a0649922551bf9d8b6815651Douglas Gregor  int i2 = -e2;
4174253736184c0717a0649922551bf9d8b6815651Douglas Gregor
4274253736184c0717a0649922551bf9d8b6815651Douglas Gregor  // C++  [over.built]p10:
4374253736184c0717a0649922551bf9d8b6815651Douglas Gregor  int i3 = ~s;
4474253736184c0717a0649922551bf9d8b6815651Douglas Gregor  bool b1 = !s;
4574253736184c0717a0649922551bf9d8b6815651Douglas Gregor
46eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  // C++ [over.built]p12
47eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  (void)static_cast<yes&>(islong(s + l));
48eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  (void)static_cast<no&>(islong(s + s));
49eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor
5020b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  // C++ [over.built]p16
5120b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  (void)(pmf == &X::f);
5220b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  (void)(pmf == 0);
5320b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor
54eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  // C++ [over.built]p17
55eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  (void)static_cast<yes&>(islong(s % l));
56eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  (void)static_cast<yes&>(islong(l << s));
57eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  (void)static_cast<no&>(islong(s << l));
58447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor  (void)static_cast<yes&>(islong(e1 % l));
59447b69e55e1098d8df46dd99f171bfaace9ff8a0Douglas Gregor  // FIXME: should pass (void)static_cast<no&>(islong(e1 % e2));
60eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor}
61eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor
623307475eb0dd6e5d88be9392ea8247d0b6b812dfDouglas Gregorstruct ShortRef { // expected-note{{candidate function}}
63eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  operator short&();
64eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor};
65eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor
66eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregorstruct LongRef {
67eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  operator volatile long&();
68eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor};
69eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor
703307475eb0dd6e5d88be9392ea8247d0b6b812dfDouglas Gregorstruct XpmfRef { // expected-note{{candidate function}}
7120b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  operator pmf&();
7220b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor};
7320b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor
7420b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregorstruct E2Ref {
7520b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  operator E2&();
7620b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor};
7720b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor
7820b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregorvoid g(ShortRef sr, LongRef lr, E2Ref e2_ref, XpmfRef pmf_ref) {
7974253736184c0717a0649922551bf9d8b6815651Douglas Gregor  // C++ [over.built]p3
8074253736184c0717a0649922551bf9d8b6815651Douglas Gregor  short s1 = sr++;
8174253736184c0717a0649922551bf9d8b6815651Douglas Gregor
8274253736184c0717a0649922551bf9d8b6815651Douglas Gregor  // C++ [over.built]p3
8374253736184c0717a0649922551bf9d8b6815651Douglas Gregor  long l1 = lr--;
8474253736184c0717a0649922551bf9d8b6815651Douglas Gregor
85eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  // C++ [over.built]p18
86eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  short& sr1 = (sr *= lr);
87eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  volatile long& lr1 = (lr *= sr);
88eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor
8920b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  // C++ [over.built]p20:
9020b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  E2 e2r2;
9120b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  e2r2 = e2_ref;
9220b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor
9320b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  pmf &pmr = (pmf_ref = &X::f); // expected-error{{no viable overloaded '='}}
9420b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  pmf pmr2;
9520b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor  pmr2 = pmf_ref;
9620b3e9918cf7d7845c920baabc4fb2f1ac0ee1d2Douglas Gregor
97eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  // C++ [over.built]p22
98eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  short& sr2 = (sr %= lr);
99eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  volatile long& lr2 = (lr <<= sr);
100eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor
101eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  bool b1 = (sr && lr) || (sr || lr);
102eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor}
103eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor
104eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregorstruct VolatileIntPtr {
105eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  operator int volatile *();
106eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor};
107eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor
108eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregorstruct ConstIntPtr {
109eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  operator int const *();
110eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor};
111eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor
11274253736184c0717a0649922551bf9d8b6815651Douglas Gregorstruct VolatileIntPtrRef {
11374253736184c0717a0649922551bf9d8b6815651Douglas Gregor  operator int volatile *&();
11474253736184c0717a0649922551bf9d8b6815651Douglas Gregor};
11574253736184c0717a0649922551bf9d8b6815651Douglas Gregor
11674253736184c0717a0649922551bf9d8b6815651Douglas Gregorstruct ConstIntPtrRef {
11774253736184c0717a0649922551bf9d8b6815651Douglas Gregor  operator int const *&();
11874253736184c0717a0649922551bf9d8b6815651Douglas Gregor};
11974253736184c0717a0649922551bf9d8b6815651Douglas Gregor
12074253736184c0717a0649922551bf9d8b6815651Douglas Gregorvoid test_with_ptrs(VolatileIntPtr vip, ConstIntPtr cip, ShortRef sr,
12174253736184c0717a0649922551bf9d8b6815651Douglas Gregor                    VolatileIntPtrRef vipr, ConstIntPtrRef cipr) {
122eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  const int& cir1 = cip[sr];
123eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  const int& cir2 = sr[cip];
124eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  volatile int& vir1 = vip[sr];
125eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  volatile int& vir2 = sr[vip];
126eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  bool b1 = (vip == cip);
127eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor  long p1 = vip - cip;
12874253736184c0717a0649922551bf9d8b6815651Douglas Gregor
12974253736184c0717a0649922551bf9d8b6815651Douglas Gregor  // C++ [over.built]p5:
13074253736184c0717a0649922551bf9d8b6815651Douglas Gregor  int volatile *vip1 = vipr++;
13174253736184c0717a0649922551bf9d8b6815651Douglas Gregor  int const *cip1 = cipr++;
13274253736184c0717a0649922551bf9d8b6815651Douglas Gregor  int volatile *&vipr1 = ++vipr;
13374253736184c0717a0649922551bf9d8b6815651Douglas Gregor  int const *&cipr1 = --cipr;
13474253736184c0717a0649922551bf9d8b6815651Douglas Gregor
13574253736184c0717a0649922551bf9d8b6815651Douglas Gregor  // C++ [over.built]p6:
13674253736184c0717a0649922551bf9d8b6815651Douglas Gregor  int volatile &ivr = *vip;
13774253736184c0717a0649922551bf9d8b6815651Douglas Gregor
13874253736184c0717a0649922551bf9d8b6815651Douglas Gregor  // C++ [over.built]p8:
13974253736184c0717a0649922551bf9d8b6815651Douglas Gregor  int volatile *vip2 = +vip;
14074253736184c0717a0649922551bf9d8b6815651Douglas Gregor  int i1 = +sr;
14174253736184c0717a0649922551bf9d8b6815651Douglas Gregor  int i2 = -sr;
142337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor
143337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor  // C++ [over.built]p13:
144337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor  int volatile &ivr2 = vip[17];
145337c6b9f5d502dc1c5acea628bf7bf9e828efc0eDouglas Gregor  int const &icr2 = 17[cip];
146eb8f3063257a392f15aea48d42fb73ec51afc548Douglas Gregor}
14774253736184c0717a0649922551bf9d8b6815651Douglas Gregor
14888b4bf202a6bb67ed241281b8dea973f38df2782Douglas Gregor// C++ [over.match.open]p4
14988b4bf202a6bb67ed241281b8dea973f38df2782Douglas Gregor
15088b4bf202a6bb67ed241281b8dea973f38df2782Douglas Gregorvoid test_assign_restrictions(ShortRef& sr) {
1518593c7810fba6548679e7c89d8eaccebf4d5ec20Sebastian Redl  sr = (short)0; // expected-error{{no viable overloaded '='}}
15288b4bf202a6bb67ed241281b8dea973f38df2782Douglas Gregor}
153652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregor
154652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregorstruct Base { };
155652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregorstruct Derived1 : Base { };
156652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregorstruct Derived2 : Base { };
157652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregor
158652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregortemplate<typename T>
159652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregorstruct ConvertibleToPtrOf {
160652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregor  operator T*();
161652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregor};
162652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregor
163652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregorbool test_with_base_ptrs(ConvertibleToPtrOf<Derived1> d1,
164652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregor                         ConvertibleToPtrOf<Derived2> d2) {
165652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregor  return d1 == d2; // expected-error{{invalid operands}}
166652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregor}
167652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregor
168652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregor// DR425
169652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregorstruct A {
170652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregor  template< typename T > operator T() const;
171652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregor};
172652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregor
173652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregorvoid test_dr425(A a) {
174652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregor  // FIXME: lots of candidates here!
175652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregor  (void)(1.0f * a); // expected-error{{ambiguous}} \
176652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregor                    // expected-note 81{{candidate}}
177652371ad0427b2310ff01ea22fdc37f02d19abe8Douglas Gregor}
178