// RUN: %clang_cc1 -verify %s -DTEST=1 // RUN: %clang_cc1 -verify %s -DTEST=2 // RUN: %clang_cc1 -verify %s -DTEST=3 // REQUIRES: thread_support // FIXME: Detection of, or recovery from, stack exhaustion does not work on // NetBSD at the moment. Since this is a best-effort mitigation for exceeding // implementation limits, just disable the test. // UNSUPPORTED: system-netbsd // asan has own stack-overflow check. // UNSUPPORTED: asan // expected-warning@* 0-1{{stack nearly exhausted}} // expected-note@* 0+{{}} #if TEST == 1 template struct X : X {}; template<> struct X<0> {}; X<1000> x; template struct tuple {}; template auto f(tuple t) -> decltype(f(tuple(t))) {} // expected-error {{exceeded maximum depth}} void g() { f(tuple()); } int f(X<0>); template auto f(X) -> f(X()); int k = f(X<1000>()); #elif TEST == 2 namespace template_argument_recursion { struct ostream; template T &&declval(); namespace mlir { template() << declval())> ostream &operator<<(ostream& os, const T& obj); // expected-error {{exceeded maximum depth}} struct Value; } void printFunctionalType(ostream &os, mlir::Value &v) { os << v; } } #elif TEST == 3 namespace template_parameter_type_recursion { struct ostream; template T &&declval(); template struct enable_if { using type = T; }; namespace mlir { template() << declval(), void*>::type = nullptr> ostream &operator<<(ostream& os, const T& obj); // expected-error {{exceeded maximum depth}} struct Value; } void printFunctionalType(ostream &os, mlir::Value &v) { os << v; } } #else #error unknown test #endif