summaryrefslogtreecommitdiffstats
path: root/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp')
-rw-r--r--test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp177
1 files changed, 177 insertions, 0 deletions
diff --git a/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp b/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp
new file mode 100644
index 0000000..58bbbb2
--- /dev/null
+++ b/test/SemaCXX/cxx1y-contextual-conversion-tweaks.cpp
@@ -0,0 +1,177 @@
+// RUN: %clang_cc1 -std=c++11 -verify -fsyntax-only %s
+// RUN: %clang_cc1 -std=c++1y %s -verify -DCXX1Y
+
+// Explicit member declarations behave as in C++11.
+
+namespace n3323_example {
+
+ template <class T> class zero_init {
+ public:
+ zero_init() : val(static_cast<T>(0)) {}
+ zero_init(T val) : val(val) {}
+
+ operator T &() { return val; } //@13
+ operator T() const { return val; } //@14
+
+ private:
+ T val;
+ };
+
+ void Delete() {
+ zero_init<int *> p;
+ p = new int(7);
+ delete p; //@23
+ delete (p + 0);
+ delete + p;
+ }
+
+ void Switch() {
+ zero_init<int> i;
+ i = 7;
+ switch (i) {} // @31
+ switch (i + 0) {}
+ switch (+i) {}
+ }
+}
+
+#ifdef CXX1Y
+#else
+//expected-error@23 {{ambiguous conversion of delete expression of type 'zero_init<int *>' to a pointer}}
+//expected-note@13 {{conversion to pointer type 'int *'}}
+//expected-note@14 {{conversion to pointer type 'int *'}}
+//expected-error@31 {{multiple conversions from switch condition type 'zero_init<int>' to an integral or enumeration type}}
+//expected-note@13 {{conversion to integral type 'int'}}
+//expected-note@14 {{conversion to integral type 'int'}}
+#endif
+
+namespace extended_examples {
+
+ struct A0 {
+ operator int(); // matching and viable
+ };
+
+ struct A1 {
+ operator int() &&; // matching and not viable
+ };
+
+ struct A2 {
+ operator float(); // not matching
+ };
+
+ struct A3 {
+ template<typename T> operator T(); // not matching (ambiguous anyway)
+ };
+
+ struct A4 {
+ template<typename T> operator int(); // not matching (ambiguous anyway)
+ };
+
+ struct B1 {
+ operator int() &&; // @70
+ operator int(); // @71 -- duplicate declaration with different qualifier is not allowed
+ };
+
+ struct B2 {
+ operator int() &&; // matching but not viable
+ operator float(); // not matching
+ };
+
+ void foo(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4, B2 b2) {
+ switch (a0) {}
+ switch (a1) {} // @81 -- fails for different reasons
+ switch (a2) {} // @82
+ switch (a3) {} // @83
+ switch (a4) {} // @84
+ switch (b2) {} // @85 -- fails for different reasons
+ }
+}
+
+//expected-error@71 {{cannot overload a member function without a ref-qualifier with a member function with ref-qualifier '&&'}}
+//expected-note@70 {{previous declaration is here}}
+//expected-error@82 {{statement requires expression of integer type ('extended_examples::A2' invalid)}}
+//expected-error@83 {{statement requires expression of integer type ('extended_examples::A3' invalid)}}
+//expected-error@84 {{statement requires expression of integer type ('extended_examples::A4' invalid)}}
+
+#ifdef CXX1Y
+//expected-error@81 {{statement requires expression of integer type ('extended_examples::A1' invalid)}}
+//expected-error@85 {{statement requires expression of integer type ('extended_examples::B2' invalid)}}
+#else
+//expected-error@81 {{cannot initialize object parameter of type 'extended_examples::A1' with an expression of type 'extended_examples::A1'}}
+//expected-error@85 {{cannot initialize object parameter of type 'extended_examples::B2' with an expression of type 'extended_examples::B2'}}
+#endif
+
+namespace extended_examples_cxx1y {
+
+ struct A1 { // leads to viable match in C++1y, and no viable match in C++11
+ operator int() &&; // matching but not viable
+ template <typename T> operator T(); // In C++1y: matching and viable, since disambiguated by L.100
+ };
+
+ struct A2 { // leads to ambiguity in C++1y, and no viable match in C++11
+ operator int() &&; // matching but not viable
+ template <typename T> operator int(); // In C++1y: matching but ambiguous (disambiguated by L.105).
+ };
+
+ struct B1 { // leads to one viable match in both cases
+ operator int(); // matching and viable
+ template <typename T> operator T(); // In C++1y: matching and viable, since disambiguated by L.110
+ };
+
+ struct B2 { // leads to one viable match in both cases
+ operator int(); // matching and viable
+ template <typename T> operator int(); // In C++1y: matching but ambiguous, since disambiguated by L.115
+ };
+
+ struct C { // leads to no match in both cases
+ operator float(); // not matching
+ template <typename T> operator T(); // In C++1y: not matching, nor viable.
+ };
+
+ struct D { // leads to viable match in C++1y, and no viable match in C++11
+ operator int() &&; // matching but not viable
+ operator float(); // not matching
+ template <typename T> operator T(); // In C++1y: matching and viable, since disambiguated by L.125
+ };
+
+
+ void foo(A1 a1, A2 a2, B1 b1, B2 b2, C c, D d) {
+ switch (a1) {} // @138 -- should presumably call templated conversion operator to convert to int.
+ switch (a2) {} // @139
+ switch (b1) {}
+ switch (b2) {}
+ switch (c) {} // @142
+ switch (d) {} // @143
+ }
+}
+
+//expected-error@142 {{statement requires expression of integer type ('extended_examples_cxx1y::C' invalid)}}
+
+#ifdef CXX1Y
+//expected-error@139 {{statement requires expression of integer type ('extended_examples_cxx1y::A2' invalid)}}
+#else
+//expected-error@138 {{cannot initialize object parameter of type 'extended_examples_cxx1y::A1' with an expression of type 'extended_examples_cxx1y::A1'}}
+//expected-error@139 {{cannot initialize object parameter of type 'extended_examples_cxx1y::A2' with an expression of type 'extended_examples_cxx1y::A2'}}
+//expected-error@143 {{cannot initialize object parameter of type 'extended_examples_cxx1y::D' with an expression of type 'extended_examples_cxx1y::D'}}
+#endif
+
+namespace extended_examples_array_bounds {
+
+ typedef decltype(sizeof(int)) size_t;
+
+ struct Foo {
+ operator size_t(); // @162
+ operator unsigned short(); // @163
+ };
+
+ void bar() {
+ Foo x;
+ int *p = new int[x]; // @168
+ }
+}
+
+#ifdef CXX1Y
+#else
+//expected-error@168 {{ambiguous conversion of array size expression of type 'extended_examples_array_bounds::Foo' to an integral or enumeration type}}
+//expected-note@162 {{conversion to integral type 'size_t'}}
+//expected-note@163 {{conversion to integral type 'unsigned short' declared here}}
+#endif
OpenPOWER on IntegriCloud