convert-to-bool.cpp revision 7c2342dd4c9947806842e5aca3d2bb2e542853c9
1a5728872c7702ddd09537c95bc3cbd20e1f2fb09Daniel Dunbar// RUN: %clang_cc1 -fsyntax-only -verify %s
276f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorstruct ConvToBool {
376f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  operator bool() const;
476f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor};
576f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
676f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorstruct ConvToInt {
776f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  operator int();
876f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor};
976f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
1076f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorstruct ExplicitConvToBool {
1176f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  explicit operator bool(); // expected-warning{{explicit conversion functions are a C++0x extension}}
1276f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor};
1376f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
1476f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorvoid test_conv_to_bool(ConvToBool ctb, ConvToInt cti, ExplicitConvToBool ecb) {
1576f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  if (ctb) { }
1676f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  if (cti) { }
1776f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  if (ecb) { }
1876f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  for (; ctb; ) { }
1976f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  for (; cti; ) { }
2076f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  for (; ecb; ) { }
2176f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  while (ctb) { };
2276f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  while (cti) { }
2376f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  while (ecb) { }
2476f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  do { } while (ctb);
2576f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  do { } while (cti);
2676f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  do { } while (ecb);
2776f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
2876f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  if (!ctb) { }
2976f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  if (!cti) { }
3076f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  if (!ecb) { }
3176f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
3276f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  bool b1 = !ecb;
3376f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  if (ctb && ecb) { }
3476f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  bool b2 = ctb && ecb;
3576f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  if (ctb || ecb) { }
3676f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  bool b3 = ctb || ecb;
3776f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor}
3876f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
39fa047648b2a5502d7eef117adb4777eb9a63baa6Douglas Gregorvoid accepts_bool(bool) { } // expected-note{{candidate function}}
4076f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
4176f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorstruct ExplicitConvToRef {
4276f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  explicit operator int&(); // expected-warning{{explicit conversion functions are a C++0x extension}}
4376f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor};
4476f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
4576f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorvoid test_explicit_bool(ExplicitConvToBool ecb) {
4676f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  bool b1(ecb); // okay
477c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  bool b2 = ecb; // expected-error{{no viable conversion from 'ExplicitConvToBool' to 'bool'}}
48fa047648b2a5502d7eef117adb4777eb9a63baa6Douglas Gregor  accepts_bool(ecb); // expected-error{{no matching function for call to}}
4976f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor}
5076f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
5176f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorvoid test_explicit_conv_to_ref(ExplicitConvToRef ecr) {
527c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  int& i1 = ecr; // expected-error{{non-const lvalue reference to type 'int' cannot bind to a value of unrelated type 'ExplicitConvToRef'}}
5376f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  int& i2(ecr); // okay
5476f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor}
5576f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
5676f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorstruct A { };
5776f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorstruct B { };
5876f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorstruct C {
5976f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  explicit operator A&(); // expected-warning{{explicit conversion functions are a C++0x extension}}
6020093b4bf698f292c664676987541d5103b65b15Douglas Gregor  operator B&(); // expected-note{{candidate}}
6176f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor};
6276f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
6376f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregorvoid test_copy_init_conversions(C c) {
647c2342dd4c9947806842e5aca3d2bb2e542853c9John McCall  A &a = c; // expected-error{{no viable conversion from 'C' to 'A'}}
6576f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor  B &b = b; // okay
6676f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor}
6776f7d287020a0b4996d6e9d3968d5bd9a39f7d84Douglas Gregor
68