brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.8 KiB · 65d8345 Raw
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