brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.5 KiB · 44b5800 Raw
168 lines · cpp
1// RUN: %clang_cc1 -fsyntax-only -verify %s2// RUN: %clang_cc1 -fsyntax-only -verify -std=c++98 %s3// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s4 5// PR46076template <class T> struct X {};7 8template <> struct X<char>9{10  static char* g();11};12 13template <class T> struct X2 {};14 15template <class U>16struct X2<U*> {17  static void f() {18    X<U>::g();19  }20};21 22void a(char *a, char *b) {X2<char*>::f();}23 24namespace WonkyAccess {25  template<typename T>26  struct X {27    int m;28  };29 30  template<typename U>31  class Y;32 33  template<typename U>34  struct Y<U*> : X<U> { };35 36  template<>37  struct Y<float*> : X<float> { };38 39  int f(Y<int*> y, Y<float*> y2) {40    return y.m + y2.m;41  }42}43 44namespace rdar9169404 {45  template<typename T, T N> struct X { };46  template<bool C> struct X<bool, C> {47    typedef int type;48  };49 50  X<bool, -1>::type value;51#if __cplusplus >= 201103L52  // expected-error@-2 {{non-type template argument evaluates to -1, which cannot be narrowed to type 'bool'}}53#endif54}55 56namespace rdar39524996 {57  template <typename T, typename U>58  struct enable_if_not_same59  {60    typedef void type;61  };62  template <typename T>63  struct enable_if_not_same<T, T>;64 65  template <typename T>66  struct Wrapper {67    // Assertion triggered on trying to set twice the same partial specialization68    // enable_if_not_same<int, int>69    template <class U>70    Wrapper(const Wrapper<U>& other,71            typename enable_if_not_same<U, T>::type* = 0) {}72 73    explicit Wrapper(int i) {}74  };75 76  template <class T>77  struct Container {78    // It is important that the struct has implicit copy and move constructors.79    Container() : x() {}80 81    template <class U>82    Container(const Container<U>& other) : x(static_cast<T>(other.x)) {}83 84    // Implicit constructors are member-wise, so the field triggers instantiation85    // of T constructors and we instantiate all of them for overloading purposes.86    T x;87  };88 89  void takesWrapperInContainer(const Container< Wrapper<int> >& c);90  void test() {91    // Type mismatch triggers initialization with conversion which requires92    // implicit constructors to be instantiated.93    Container<int> c;94    takesWrapperInContainer(c);95  }96}97 98namespace InstantiationDependent {99  template<typename> using ignore = void; // expected-warning 0-1{{extension}}100  template<typename T, typename = void> struct A {101    static const bool specialized = false;102  };103  template<typename T> struct Hide { typedef void type; };104  template<typename T> struct A<T, Hide<ignore<typename T::type> >::type> {105    static const bool specialized = true;106  };107 108  struct X {};109  struct Y { typedef int type; };110  _Static_assert(!A<X>::specialized, "");111  _Static_assert(A<Y>::specialized, "");112}113 114namespace IgnorePartialSubstitution {115  template <typename... T> struct tuple {}; // expected-warning 0-1{{extension}}116  template <typename> struct IsTuple {117    enum { value = false };118  };119  template <typename... Us> struct IsTuple<tuple<Us...> > { // expected-warning 0-1{{extension}}120    enum { value = true };121  };122 123  template <bool...> using ignore = void; // expected-warning 0-2{{extension}}124  template <class... Pred> ignore<Pred::value...> helper(); // expected-warning 0-1{{extension}}125 126  using S = IsTuple<tuple<int> >; // expected-warning 0-1{{extension}}127 128  // This used to pick the primary template, because we got confused and129  // thought that template parameter 0 was the current partially-substituted130  // pack (from `helper`) during the deduction for the partial specialization.131  void f() { helper<S>(); }132 133  _Static_assert(S::value, "");134}135 136namespace GH60778 {137  template <bool B = false> class ClassTemplate {138  public:139      template <typename T, typename = void> class Nested {};140  };141 142  template <typename DerivedType> class Base {};143 144  template <>145  template <typename T>146  class ClassTemplate<>::Nested<T> : public Base<ClassTemplate<>::Nested<T> > {};147 148  void use() {149    // This should instantiate the body of Nested with the template arguments150    // from the Partial Specialization. This would previously get confused and151    // get the template arguments from the primary template instead.152    ClassTemplate<>::Nested<int> instantiation;153  }154}155#if __cplusplus >= 201103L156namespace GH162855 {157  template <class...> using A = int;158  template <class, int> struct B;159  template <class...> struct C;160  template <template <class, int...> class TT, long... X>161  struct C<TT<int, X...>> {162    template <class... Y> using l = A<B<Y, X>...>;163  };164  template <class> struct D;165  template struct C<D<int>>;166} // namespace GH162855167#endif168