1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s
287d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s
387d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar
576f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorstruct ConvToBool {
676f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  operator bool() const;
776f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor};
876f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
976f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorstruct ConvToInt {
1076f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  operator int();
1176f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor};
1276f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
1376f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorstruct ExplicitConvToBool {
1487d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  explicit operator bool();
1587d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#if __cplusplus <= 199711L // C++03 or earlier modes
1687d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // expected-warning@-2{{explicit conversion functions are a C++11 extension}}
1787d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#endif
1876f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor};
1976f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
2076f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorvoid test_conv_to_bool(ConvToBool ctb, ConvToInt cti, ExplicitConvToBool ecb) {
2176f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  if (ctb) { }
2276f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  if (cti) { }
2376f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  if (ecb) { }
2476f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  for (; ctb; ) { }
2576f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  for (; cti; ) { }
2676f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  for (; ecb; ) { }
2776f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  while (ctb) { };
2876f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  while (cti) { }
2976f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  while (ecb) { }
3076f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  do { } while (ctb);
3176f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  do { } while (cti);
3276f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  do { } while (ecb);
3376f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
3476f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  if (!ctb) { }
3576f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  if (!cti) { }
3676f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  if (!ecb) { }
3776f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
3876f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  bool b1 = !ecb;
3976f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  if (ctb && ecb) { }
4076f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  bool b2 = ctb && ecb;
4176f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  if (ctb || ecb) { }
4276f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  bool b3 = ctb || ecb;
4376f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor}
4476f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
45fa047648b2a5502d7eef117adb4777eb9a63baa6Douglas Gregorvoid accepts_bool(bool) { } // expected-note{{candidate function}}
4676f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
4776f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorstruct ExplicitConvToRef {
4887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  explicit operator int&();
4987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#if (__cplusplus <= 199711L) // C++03 or earlier modes
5087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  // expected-warning@-2{{explicit conversion functions are a C++11 extension}}
5187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#endif
5276f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor};
5376f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
5476f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorvoid test_explicit_bool(ExplicitConvToBool ecb) {
5576f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  bool b1(ecb); // okay
567c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  bool b2 = ecb; // expected-error{{no viable conversion from 'ExplicitConvToBool' to 'bool'}}
57fa047648b2a5502d7eef117adb4777eb9a63baa6Douglas Gregor  accepts_bool(ecb); // expected-error{{no matching function for call to}}
5876f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor}
5976f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
6076f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorvoid test_explicit_conv_to_ref(ExplicitConvToRef ecr) {
617c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  int& i1 = ecr; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'ExplicitConvToRef'}}
6276f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  int& i2(ecr); // okay
6376f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor}
6476f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
6576f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorstruct A { };
6676f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorstruct B { };
6776f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorstruct C {
6887d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar  explicit operator A&();
6987d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#if __cplusplus <= 199711L // C++03 or earlier modes
7087d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar// expected-warning@-2{{explicit conversion functions are a C++11 extension}}
7187d948ecccffea9e9e37d0d053b246e2d6d6c47bPirama Arumuga Nainar#endif
7220093b4bf698f292c664676987541d5103b65b15Douglas Gregor  operator B&(); // expected-note{{candidate}}
7376f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor};
7476f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
7576f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorvoid test_copy_init_conversions(C c) {
767c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  A &a = c; // expected-error{{no viable conversion from 'C' to 'A'}}
778be9e77f7e532866fa0ef2bc8c3cd549f0cc8da2Hans Wennborg  B &b = c; // okay
7876f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor}
79