1 // RUN: %clang_cc1 -fsyntax-only -verify -triple %itanium_abi_triple -std=c++11 -ftemplate-depth=16 -fcxx-exceptions -fexceptions %s
3 // DR1330: an exception specification for a function template is only
4 // instantiated when it is needed.
6 // Note: the test is Itanium-specific because it depends on key functions in the
9 template<typename T
> void f1(T
*) throw(T
); // expected-error{{incomplete type 'Incomplete' is not allowed in exception specification}}
10 struct Incomplete
; // expected-note{{forward}}
12 void test_f1(Incomplete
*incomplete_p
, int *int_p
) {
14 f1(incomplete_p
); // expected-note{{instantiation of exception spec}}
17 template<typename T
> struct A
{
18 template<typename U
> struct B
{
19 static void f() noexcept(A
<U
>().n
);
22 constexpr A() : n(true) {}
26 static_assert(noexcept(A
<int>::B
<char>::f()), "");
28 template<unsigned N
> struct S
{
29 static void recurse() noexcept(noexcept(S
<N
+1>::recurse())); // \
30 // expected-error {{no member named 'recurse'}} \
31 // expected-note 9{{instantiation of exception spec}}
34 template<> struct S
<10> {};
35 void (*pFn2
)() noexcept
= &S
<0>::recurse
; // expected-note {{instantiation of exception spec}} expected-error {{not superset}}
38 namespace dr1330_example
{
39 template <class T
> struct A
{
40 void f(...) throw (typename
T::X
);
49 template<typename T
> static void f() throw(typename
T::X
);
50 typedef decltype(f
<S
>()) X
; // expected-error {{exception specification is not available}}
54 template<typename T
> static void f() throw(T
**);
55 typedef decltype(f
<S
>()) X
; // expected-error {{exception specification is not available}}
60 void f() noexcept(T::error
);
61 void (g
)() noexcept(T::error
);
66 namespace core_19754_example
{
67 template<typename T
> T
declval() noexcept
;
69 template<typename T
, typename
= decltype(T(declval
<T
&&>()))>
70 struct is_movable
{ static const bool value
= true; };
75 void irrelevant(wrap
&p
) noexcept(is_movable
<T
>::value
);
81 base(const typename
T::type1
&);
82 base(const typename
T::type2
&);
87 wrap
<typename
T::base
> base
;
92 wrap
<typename
T::base
> base
;
96 typedef base
<types
> base
;
97 typedef type1
<types
> type1
;
98 typedef type2
<types
> type2
;
101 base
<types
> val
= base
<types
>();
105 template <typename T
> void f1(T
) throw(typename
T::exception
); // expected-note {{candidate}}
106 template <typename T
> void f1(T
, int = 0) throw(typename
T::noitpecxe
); // expected-note {{candidate}}
108 template <typename T
> void f2(T
) noexcept(T::throws
); // expected-note {{candidate}}
109 template <typename T
> void f2(T
, int = 0) noexcept(T::sworht
); // expected-note {{candidate}}
112 f1(0); // expected-error {{ambiguous}}
113 f2(0); // expected-error {{ambiguous}}
117 struct Exc1
{ char c
[4]; };
118 struct Exc2
{ double x
, y
, z
; };
120 virtual void f() noexcept
; // expected-note {{overridden}}
122 template<typename T
> struct Derived
: Base
{
123 void f() noexcept (sizeof(T
) == 4); // expected-error {{is more lax}}
124 void g() noexcept (T::error
);
127 Derived
<Exc1
> d1
; // ok
128 Derived
<Exc2
> d2
; // expected-note {{in instantiation of}}
130 // If the vtable for a derived class is used, the exception specification of
131 // any member function which ends up in that vtable is needed, even if it was
132 // declared in a base class.
134 template<bool *B
> struct T
{
135 virtual void f() noexcept (*B
); // expected-error {{constant expression}} expected-note {{read of non-const}}
137 bool b
; // expected-note {{here}}
138 struct X
: public T
<&b
> {
141 void X::g() {} // expected-note {{in instantiation of}}
145 template<bool B
> void check() { static_assert(B
, ""); }
146 template<bool B
, bool B2
, bool ...Bs
> void check() { static_assert(B
, ""); check
<B2
, Bs
...>(); }
148 template<typename
...T
> void consume(T
...);
150 template<typename
...T
> void f(void (*...p
)() throw (T
)) {
151 void (*q
[])() = { p
... };
154 template<bool ...B
> void g(void (*...p
)() noexcept (B
)) {
156 check
<noexcept(p()) == B
...>();
158 template<typename
...T
> void i() {
159 consume([]() throw(T
) {} ...);
160 consume([]() noexcept(sizeof(T
) == 4) {} ...);
162 template<bool ...B
> void j() {
163 consume([](void (*p
)() noexcept(B
)) { // expected-note {{substituting into a lambda}}
164 void (*q
)() noexcept
= p
; // expected-error {{not superset of source}}
169 f
<int, char, double>(nullptr, nullptr, nullptr);
170 g
<true, false, true>(nullptr, nullptr, nullptr);
171 i
<int, long, short>();
173 j
<true, false>(); // expected-note {{in instantiation of}}
178 namespace NondefDecls
{
179 template<typename T
> void f1() {
180 int g1(int) noexcept(T::error
); // expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
182 template void f1
<int>(); // expected-note{{in instantiation of function template specialization 'NondefDecls::f1<int>' requested here}}