instantiate-self.cpp 2.2 KB

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