116 lines · cpp
1// RUN: %clang_cc1 -std=c++23 -fsyntax-only -verify=expected,cxx23 %s2// RUN: %clang_cc1 -std=c++20 -fsyntax-only -verify=expected,cxx98_20 %s3// RUN: %clang_cc1 -std=c++98 -fsyntax-only -verify=expected,cxx98_20 %s4// RUN: %clang_cc1 -fsyntax-only -verify=expected,cxx98_20 %s5 6struct A {7 template <class T> operator T*();8};9 10template <class T> A::operator T*() { return 0; }11template <> A::operator char*(){ return 0; } // specialization12template A::operator void*(); // explicit instantiation13 14int main() {15 A a;16 int *ip;17 ip = a.operator int*();18}19 20// PR574221namespace PR5742 {22 template <class T> struct A { };23 template <class T> struct B { };24 25 struct S {26 template <class T> operator T();27 } s;28 29 void f() {30 s.operator A<A<int> >();31 s.operator A<B<int> >();32 s.operator A<B<A<int> > >();33 }34}35 36// PR576237class Foo {38 public:39 template <typename T> operator T();40 41 template <typename T>42 T As() {43 return this->operator T();44 }45 46 template <typename T>47 T As2() {48 return operator T();49 }50 51 int AsInt() {52 return this->operator int();53 }54};55 56template float Foo::As();57template double Foo::As2();58 59template<int B1> struct B {};60template<class C1> struct C {};61template<class D1, int D2> struct D {};62 63// Partial ordering with conversion function templates.64struct X0 {65 template<typename T> operator T*() {66 T x = 1; // expected-note{{variable 'x' declared const here}}67 x = 17; // expected-error{{cannot assign to variable 'x' with const-qualified type 'const int'}}68 }69 70 template<typename T> operator T*() const; // expected-note{{explicit instantiation refers here}}71 template<int V> operator B<V>() const; // expected-note{{explicit instantiation refers here}}72 template<class T, int V> operator C<T[V]>() const; // expected-note{{explicit instantiation refers here}}73#if __cplusplus >= 201103L74 template<int V> operator D<decltype(V), V>() const; // expected-note{{explicit instantiation refers here}}75#endif76 77 template<typename T> operator const T*() const {78 T x = T();79 return x; // cxx98_20-error{{cannot initialize return object of type 'const char *' with an lvalue of type 'char'}} \80 // cxx98_20-error{{cannot initialize return object of type 'const int *' with an lvalue of type 'int'}} \81 // cxx23-error{{cannot initialize return object of type 'const char *' with an rvalue of type 'char'}} \82 // cxx23-error{{cannot initialize return object of type 'const int *' with an rvalue of type 'int'}}83 }84};85 86template X0::operator const char*() const; // expected-note{{'X0::operator const char *<char>' requested here}}87template X0::operator const int*(); // expected-note{{'X0::operator const int *<const int>' requested here}}88// FIXME: These diagnostics are printing canonical types.89template X0::operator float*() const; // expected-error{{explicit instantiation of undefined function template 'operator type-parameter-0-0 *'}}90template X0::operator B<0>() const; // expected-error {{undefined function template 'operator B<value-parameter-0-0>'}}91// FIXME: Within the above issue were we print canonical types here, printing the array92// index expression as non-canonical is extra bad.93template X0::operator C<int[1]>() const; // expected-error {{undefined function template 'operator C<type-parameter-0-0[V]>'}}94#if __cplusplus >= 201103L95template X0::operator D<int, 0>() const; // expected-error {{undefined function template 'operator D<decltype(value-parameter-0-0), value-parameter-0-0>'}}96#endif97 98void test_X0(X0 x0, const X0 &x0c) {99 x0.operator const int*(); // expected-note{{in instantiation of function template specialization}}100 x0.operator float *();101 x0c.operator const char*();102}103 104namespace PR14211 {105template <class U> struct X {106 void foo(U){}107 template <class T> void foo(T){}108 109 template <class T> void bar(T){}110 void bar(U){}111};112 113template void X<int>::foo(int);114template void X<int>::bar(int);115}116