196 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -verify=expected,cxx11 -fsyntax-only -pedantic-errors %s2// RUN: %clang_cc1 -std=c++14 -verify=expected,cxx14 -fsyntax-only -pedantic-errors %s -DCXX1Y3 4// Explicit member declarations behave as in C++11.5 6namespace n3323_example {7 8 template <class T> class zero_init {9 public:10 zero_init() : val(static_cast<T>(0)) {}11 zero_init(T val) : val(val) {}12 13 operator T &() { return val; } //@1314 operator T() const { return val; } //@1415 16 private:17 T val;18 };19 20 void Delete() {21 zero_init<int *> p;22 p = new int(7);23 delete p; //@2324 delete (p + 0);25 delete + p;26 }27 28 void Switch() {29 zero_init<int> i;30 i = 7;31 switch (i) {} // @3132 switch (i + 0) {}33 switch (+i) {}34 }35}36 37#ifdef CXX1Y38#else39//expected-error@23 {{ambiguous conversion of delete expression of type 'zero_init<int *>' to a pointer}}40//expected-note@13 {{conversion to pointer type 'int *'}}41//expected-note@14 {{conversion to pointer type 'int *'}}42//expected-error@31 {{multiple conversions from switch condition type 'zero_init<int>' to an integral or enumeration type}}43//expected-note@13 {{conversion to integral type 'int'}}44//expected-note@14 {{conversion to integral type 'int'}}45#endif46 47namespace extended_examples {48 49 struct A0 {50 operator int(); // matching and viable51 };52 53 struct A1 {54 operator int() &&; // matching and not viable55 };56 57 struct A2 {58 operator float(); // not matching59 };60 61 struct A3 {62 template<typename T> operator T(); // not matching (ambiguous anyway)63 };64 65 struct A4 {66 template<typename T> operator int(); // not matching (ambiguous anyway)67 };68 69 struct B1 {70 operator int() &&; // @7071 operator int(); // @71 -- duplicate declaration with different qualifier is not allowed72 };73 74 struct B2 {75 operator int() &&; // matching but not viable76 operator float(); // not matching77 };78 79 void foo(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, B2 b2) {80 switch (a0) {}81 switch (a1) {} // @81 -- fails for different reasons82 switch (a2) {} // @8283 switch (a3) {} // @8384 switch (a4) {} // @8485 switch (b2) {} // @85 -- fails for different reasons86 }87}88 89//expected-error@71 {{cannot overload a member function without a ref-qualifier with a member function with ref-qualifier '&&'}}90//expected-note@70 {{previous declaration is here}}91//expected-error@82 {{statement requires expression of integer type ('A2' invalid)}}92//expected-error@83 {{statement requires expression of integer type ('A3' invalid)}}93//expected-error@84 {{statement requires expression of integer type ('A4' invalid)}}94 95#ifdef CXX1Y96//expected-error@81 {{statement requires expression of integer type ('A1' invalid)}}97//expected-error@85 {{statement requires expression of integer type ('B2' invalid)}}98#else99//expected-error@81 {{'this' argument to member function 'operator int' is an lvalue, but function has rvalue ref-qualifier}} expected-note@54 {{'operator int' declared here}}100//expected-error@85 {{'this' argument to member function 'operator int' is an lvalue, but function has rvalue ref-qualifier}} expected-note@75 {{'operator int' declared here}}101#endif102 103namespace extended_examples_cxx1y {104 105 struct A1 { // leads to viable match in C++1y, and no viable match in C++11106 operator int() &&; // matching but not viable107 template <typename T> operator T(); // In C++1y: matching and viable, since disambiguated by L.100108 };109 110 struct A2 { // leads to ambiguity in C++1y, and no viable match in C++11111 operator int() &&; // matching but not viable112 template <typename T> operator int(); // In C++1y: matching but ambiguous (disambiguated by L.105).113 };114 115 struct B1 { // leads to one viable match in both cases116 operator int(); // matching and viable117 template <typename T> operator T(); // In C++1y: matching and viable, since disambiguated by L.110118 };119 120 struct B2 { // leads to one viable match in both cases121 operator int(); // matching and viable122 template <typename T> operator int(); // In C++1y: matching but ambiguous, since disambiguated by L.115123 };124 125 struct C { // leads to no match in both cases126 operator float(); // not matching127 template <typename T> operator T(); // In C++1y: not matching, nor viable.128 };129 130 struct D { // leads to viable match in C++1y, and no viable match in C++11131 operator int() &&; // matching but not viable132 operator float(); // not matching133 template <typename T> operator T(); // In C++1y: matching and viable, since disambiguated by L.125134 };135 136 137 void foo(A1 a1, A2 a2, B1 b1, B2 b2, C c, D d) {138 switch (a1) {} // @138 -- should presumably call templated conversion operator to convert to int.139 switch (a2) {} // @139140 switch (b1) {}141 switch (b2) {}142 switch (c) {} // @142143 switch (d) {} // @143144 }145}146 147//expected-error@142 {{statement requires expression of integer type ('C' invalid)}}148 149#ifdef CXX1Y150//expected-error@139 {{statement requires expression of integer type ('A2' invalid)}}151#else152//expected-error@138 {{'this' argument to member function 'operator int' is an lvalue, but function has rvalue ref-qualifier}} expected-note@106 {{'operator int' declared here}}153//expected-error@139 {{'this' argument to member function 'operator int' is an lvalue, but function has rvalue ref-qualifier}} expected-note@111 {{'operator int' declared here}}154//expected-error@143 {{'this' argument to member function 'operator int' is an lvalue, but function has rvalue ref-qualifier}} expected-note@131 {{'operator int' declared here}}155#endif156 157namespace extended_examples_array_bounds {158 159 typedef decltype(sizeof(int)) size_t;160 161 struct X {162 constexpr operator size_t() const { return 1; } // cxx11-note 3{{conversion}}163 constexpr operator unsigned short() const { return 0; } // cxx11-note 3{{conversion}}164 };165 166 void f() {167 X x;168 int *p = new int[x]; // cxx11-error {{ambiguous}}169 170 int arr[x]; // cxx11-error {{ambiguous}}171 int (*q)[1] = new int[1][x]; // cxx11-error {{ambiguous}}172 }173 174 struct Y {175 constexpr operator float() const { return 0.0f; } // cxx14-note 3{{candidate}}176 constexpr operator int() const { return 1; } // cxx14-note 3{{candidate}}177 };178 179 void g() {180 Y y;181 int *p = new int[y]; // cxx14-error {{ambiguous}}182 183 int arr[y]; // cxx14-error {{ambiguous}}184 int (*q)[1] = new int[1][y]; // cxx14-error {{ambiguous}}185 }186 187 template<int N> struct Z {188 constexpr operator int() const { return N; }189 };190 void h() {191 int arrA[Z<1>()];192 int arrB[Z<0>()]; // expected-error {{zero size array}}193 int arrC[Z<-1>()]; // expected-error {{'arrC' declared as an array with a negative size}}194 }195}196