summaryrefslogtreecommitdiffstats
path: root/test/SemaTemplate/instantiate-exception-spec-cxx11.cpp
blob: d29c8862b9aec6772734c3fda0d6bad78a788b47 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 -ftemplate-depth 16 %s

// DR1330: an exception specification for a function template is only
// instantiated when it is needed.

template<typename T> void f1(T*) throw(T); // expected-error{{incomplete type 'Incomplete' is not allowed in exception specification}}
struct Incomplete; // expected-note{{forward}}

void test_f1(Incomplete *incomplete_p, int *int_p) {
  f1(int_p);
  f1(incomplete_p); // expected-note{{instantiation of exception spec}}
}

template<typename T> struct A {
  template<typename U> struct B {
    static void f() noexcept(A<U>().n);
  };

  constexpr A() : n(true) {}
  bool n;
};

static_assert(noexcept(A<int>::B<char>::f()), "");

template<unsigned N> struct S {
  static void recurse() noexcept(noexcept(S<N+1>::recurse())); // \
  // expected-error {{no member named 'recurse'}} \
  // expected-note 9{{instantiation of exception spec}}
};
decltype(S<0>::recurse()) *pVoid1 = 0; // ok, exception spec not needed
decltype(&S<0>::recurse) pFn = 0; // ok, exception spec not needed

template<> struct S<10> {};
void (*pFn2)() noexcept = &S<0>::recurse; // expected-note {{instantiation of exception spec}}


template<typename T> T go(T a) noexcept(noexcept(go(a))); // \
// expected-error 16{{call to function 'go' that is neither visible}} \
// expected-note 16{{'go' should be declared prior to the call site}} \
// expected-error {{recursive template instantiation exceeded maximum depth of 16}} \
// expected-error {{use of undeclared identifier 'go'}} \

void f() {
  int k = go(0); // \
  // expected-note {{in instantiation of exception specification for 'go<int>' requested here}}
}


namespace dr1330_example {
  template <class T> struct A {
    void f(...) throw (typename T::X); // expected-error {{'int'}}
    void f(int);
  };

  int main() {
    A<int>().f(42);
  }

  int test2() {
    struct S {
      template<typename T>
      static int f() noexcept(noexcept(A<T>().f("boo!"))) { return 0; } // \
      // expected-note {{instantiation of exception spec}}
      typedef decltype(f<S>()) X;
    };
    S().f<S>(); // ok
    S().f<int>(); // expected-note {{instantiation of exception spec}}
  }
}

namespace core_19754_example {
  template<typename T> T declval() noexcept;

  template<typename T, typename = decltype(T(declval<T&&>()))>
  struct is_movable { static const bool value = true; };

  template<typename T>
  struct wrap {
    T val;
    void irrelevant(wrap &p) noexcept(is_movable<T>::value);
  };

  template<typename T>
  struct base {
     base() {}
     base(const typename T::type1 &);
     base(const typename T::type2 &);
  };

  template<typename T>
  struct type1 {
     wrap<typename T::base> base;
  };

  template<typename T>
  struct type2 {
     wrap<typename T::base> base;
  };

  struct types {
     typedef base<types> base;
     typedef type1<types> type1;
     typedef type2<types> type2;
  };

  base<types> val = base<types>();
}

namespace pr9485 {
  template <typename T> void f1(T) throw(typename T::exception); // expected-note {{candidate}}
  template <typename T> void f1(T, int = 0) throw(typename T::noitpecxe); // expected-note {{candidate}}

  template <typename T> void f2(T) noexcept(T::throws); // expected-note {{candidate}}
  template <typename T> void f2(T, int = 0) noexcept(T::sworht); // expected-note {{candidate}}

  void test() {
    f1(0); // expected-error {{ambiguous}}
    f2(0); // expected-error {{ambiguous}}
  }
}