reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    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
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
  153
  154
  155
  156
  157
  158
  159
  160
  161
  162
  163
  164
  165
  166
  167
  168
  169
  170
  171
  172
  173
  174
  175
  176
  177
  178
  179
  180
  181
  182
  183
  184
// RUN: %clang_cc1 -fsyntax-only -verify -triple %itanium_abi_triple -std=c++11 -ftemplate-depth 16 -fcxx-exceptions -fexceptions %s

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

// Note: the test is Itanium-specific because it depends on key functions in the
// PR12763 namespace.

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}}
};

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


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

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

  struct S {
    template<typename T> static void f() throw(typename T::X);
    typedef decltype(f<S>()) X; // expected-error {{exception specification is not available}}
  };

  struct T {
    template<typename T> static void f() throw(T**);
    typedef decltype(f<S>()) X; // expected-error {{exception specification is not available}}
  };

  template<typename T>
  struct U {
    void f() noexcept(T::error);
    void (g)() noexcept(T::error);
  };
  U<int> uint; // ok
}

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}}
  }
}

struct Exc1 { char c[4]; };
struct Exc2 { double x, y, z; };
struct Base {
  virtual void f() noexcept; // expected-note {{overridden}}
};
template<typename T> struct Derived : Base {
  void f() noexcept (sizeof(T) == 4); // expected-error {{is more lax}}
  void g() noexcept (T::error);
};

Derived<Exc1> d1; // ok
Derived<Exc2> d2; // expected-note {{in instantiation of}}

// If the vtable for a derived class is used, the exception specification of
// any member function which ends up in that vtable is needed, even if it was
// declared in a base class.
namespace PR12763 {
  template<bool *B> struct T {
    virtual void f() noexcept (*B); // expected-error {{constant expression}} expected-note {{read of non-const}}
  };
  bool b; // expected-note {{here}}
  struct X : public T<&b> {
    virtual void g();
  };
  void X::g() {} // expected-note {{in instantiation of}}
}

namespace Variadic {
  template<bool B> void check() { static_assert(B, ""); }
  template<bool B, bool B2, bool ...Bs> void check() { static_assert(B, ""); check<B2, Bs...>(); }

  template<typename ...T> void consume(T...);

  template<typename ...T> void f(void (*...p)() throw (T)) {
    void (*q[])() = { p... };
    consume((p(),0)...);
  }
  template<bool ...B> void g(void (*...p)() noexcept (B)) {
    consume((p(),0)...);
    check<noexcept(p()) == B ...>();
  }
  template<typename ...T> void i() {
    consume([]() throw(T) {} ...);
    consume([]() noexcept(sizeof(T) == 4) {} ...);
  }
  template<bool ...B> void j() {
    consume([](void (*p)() noexcept(B)) {
      void (*q)() noexcept = p; // expected-error {{not superset of source}}
    } ...);
  }

  void z() {
    f<int, char, double>(nullptr, nullptr, nullptr);
    g<true, false, true>(nullptr, nullptr, nullptr);
    i<int, long, short>();
    j<true, true>();
    j<true, false>(); // expected-note {{in instantiation of}}
  }

}

namespace NondefDecls {
  template<typename T> void f1() {
    int g1(int) noexcept(T::error); // expected-error{{type 'int' cannot be used prior to '::' because it has no members}}
  }
  template void f1<int>(); // expected-note{{in instantiation of function template specialization 'NondefDecls::f1<int>' requested here}}
}