Home | History | Annotate | Download | only in SemaTemplate
      1 // RUN: %clang_cc1 -std=c++11 -verify %s
      2 
      3 // Check that we deal with cases where the instantiation of a class template
      4 // recursively requires the instantiation of the same template.
      5 namespace test1 {
      6   template<typename T> struct A {
      7     struct B { // expected-note {{not complete until the closing '}'}}
      8       B b; // expected-error {{has incomplete type 'test1::A<int>::B'}}
      9     };
     10     B b; // expected-note {{in instantiation of}}
     11   };
     12   A<int> a; // expected-note {{in instantiation of}}
     13 }
     14 
     15 namespace test2 {
     16   template<typename T> struct A {
     17     struct B {
     18       struct C {};
     19       char c[1 + C()]; // expected-error {{invalid operands to binary expression}}
     20       friend constexpr int operator+(int, C) { return 4; }
     21     };
     22     B b; // expected-note {{in instantiation of}}
     23   };
     24   A<int> a; // expected-note {{in instantiation of}}
     25 }
     26 
     27 namespace test3 {
     28   // PR12317
     29   template<typename T> struct A {
     30     struct B {
     31       enum { Val = 1 };
     32       char c[1 + Val]; // ok
     33     };
     34     B b;
     35   };
     36   A<int> a;
     37 }
     38 
     39 namespace test4 {
     40   template<typename T> struct M { typedef int type; };
     41   template<typename T> struct A {
     42     struct B { // expected-note {{not complete until the closing '}'}}
     43       int k[typename A<typename M<T>::type>::B().k[0] + 1]; // expected-error {{incomplete type}}
     44     };
     45     B b; // expected-note {{in instantiation of}}
     46   };
     47   A<int> a; // expected-note {{in instantiation of}}
     48 }
     49 
     50 // FIXME: PR12298: Recursive constexpr function template instantiation leads to
     51 // stack overflow.
     52 #if 0
     53 namespace test5 {
     54   template<typename T> struct A {
     55     constexpr T f(T k) { return g(k); }
     56     constexpr T g(T k) {
     57       return k ? f(k-1)+1 : 0;
     58     }
     59   };
     60   // This should be accepted.
     61   constexpr int x = A<int>().f(5);
     62 }
     63 
     64 namespace test6 {
     65   template<typename T> constexpr T f(T);
     66   template<typename T> constexpr T g(T t) {
     67     typedef int arr[f(T())];
     68     return t;
     69   }
     70   template<typename T> constexpr T f(T t) {
     71     typedef int arr[g(T())];
     72     return t;
     73   }
     74   // This should be ill-formed.
     75   int n = f(0);
     76 }
     77 
     78 namespace test7 {
     79   template<typename T> constexpr T g(T t) {
     80     return t;
     81   }
     82   template<typename T> constexpr T f(T t) {
     83     typedef int arr[g(T())];
     84     return t;
     85   }
     86   // This should be accepted.
     87   int n = f(0);
     88 }
     89 #endif
     90