blob: 763b9ed41bf8a1f81f6c81e72c91e15103478566 [file] [log] [blame]
Richard Smithe6975e92012-04-17 00:58:00 +00001// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -ftemplate-depth 16 %s
2
3// DR1330: an exception specification for a function template is only
4// instantiated when it is needed.
5
6template<typename T> void f1(T*) throw(T); // expected-error{{incomplete type 'Incomplete' is not allowed in exception specification}}
7struct Incomplete; // expected-note{{forward}}
8
9void test_f1(Incomplete *incomplete_p, int *int_p) {
10 f1(int_p);
11 f1(incomplete_p); // expected-note{{instantiation of exception spec}}
12}
13
14template<typename T> struct A {
15 template<typename U> struct B {
16 static void f() noexcept(A<U>().n);
17 };
18
19 constexpr A() : n(true) {}
20 bool n;
21};
22
23static_assert(noexcept(A<int>::B<char>::f()), "");
24
25template<unsigned N> struct S {
26 static void recurse() noexcept(noexcept(S<N+1>::recurse())); // \
27 // expected-error {{no member named 'recurse'}} \
28 // expected-note 9{{instantiation of exception spec}}
29};
30decltype(S<0>::recurse()) *pVoid1 = 0; // ok, exception spec not needed
31decltype(&S<0>::recurse) pFn = 0; // ok, exception spec not needed
32
33template<> struct S<10> {};
34void (*pFn2)() noexcept = &S<0>::recurse; // expected-note {{instantiation of exception spec}}
35
36
37template<typename T> T go(T a) noexcept(noexcept(go(a))); // \
38// expected-error 16{{call to function 'go' that is neither visible}} \
39// expected-note 16{{'go' should be declared prior to the call site}} \
40// expected-error {{recursive template instantiation exceeded maximum depth of 16}} \
41// expected-error {{use of undeclared identifier 'go'}} \
42
43void f() {
44 int k = go(0); // \
45 // expected-note {{in instantiation of exception specification for 'go<int>' requested here}}
46}
47
48
49namespace dr1330_example {
50 template <class T> struct A {
51 void f(...) throw (typename T::X); // expected-error {{'int'}}
52 void f(int);
53 };
54
55 int main() {
56 A<int>().f(42);
57 }
58
59 int test2() {
60 struct S {
61 template<typename T>
62 static int f() noexcept(noexcept(A<T>().f("boo!"))) { return 0; } // \
63 // expected-note {{instantiation of exception spec}}
64 typedef decltype(f<S>()) X;
65 };
66 S().f<S>(); // ok
67 S().f<int>(); // expected-note {{instantiation of exception spec}}
68 }
69}
70
71namespace core_19754_example {
72 template<typename T> T declval() noexcept;
73
74 template<typename T, typename = decltype(T(declval<T&&>()))>
75 struct is_movable { static const bool value = true; };
76
77 template<typename T>
78 struct wrap {
79 T val;
80 void irrelevant(wrap &p) noexcept(is_movable<T>::value);
81 };
82
83 template<typename T>
84 struct base {
85 base() {}
86 base(const typename T::type1 &);
87 base(const typename T::type2 &);
88 };
89
90 template<typename T>
91 struct type1 {
92 wrap<typename T::base> base;
93 };
94
95 template<typename T>
96 struct type2 {
97 wrap<typename T::base> base;
98 };
99
100 struct types {
101 typedef base<types> base;
102 typedef type1<types> type1;
103 typedef type2<types> type2;
104 };
105
106 base<types> val = base<types>();
107}