brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.9 KiB · c8204c2 Raw
187 lines · cpp
1// RUN: %clang_cc1 -std=c++14 -verify -fexceptions -fcxx-exceptions %s2// RUN: %clang_cc1 -std=c++17 -verify -fexceptions -fcxx-exceptions %s -Wno-dynamic-exception-spec3// RUN: %clang_cc1 -std=c++14 -verify -fexceptions -fcxx-exceptions -Wno-c++1z-compat-mangling -DNO_COMPAT_MANGLING %s4// RUN: %clang_cc1 -std=c++14 -verify -fexceptions -fcxx-exceptions -Wno-noexcept-type -DNO_COMPAT_MANGLING %s5 6#if __cplusplus > 201402L7 8template<typename T> void redecl1() noexcept(noexcept(T())) {} // expected-note {{previous}}9template<typename T> void redecl1() noexcept(noexcept(T())); // ok, same type10template<typename T> void redecl1() noexcept(noexcept(T())) {} // expected-error {{redefinition}}11 12template<bool A, bool B> void redecl2() noexcept(A); // expected-note {{previous}}13template<bool A, bool B> void redecl2() noexcept(B); // expected-error {{does not match previous}}14 15// These have the same canonical type, but are still different.16template<typename A, typename B> void redecl3() throw(A); // expected-note {{previous}}17template<typename A, typename B> void redecl3() throw(B); // expected-error {{does not match previous}}18 19typedef int I;20template<bool B> void redecl4(I) noexcept(B);21template<bool B> void redecl4(I) noexcept(B);22 23void (*init_with_exact_type_a)(int) noexcept = redecl4<true>;24void (*init_with_mismatched_type_a)(int) = redecl4<true>;25auto deduce_auto_from_noexcept_function_ptr_a = redecl4<true>;26using DeducedType_a = decltype(deduce_auto_from_noexcept_function_ptr_a);27using DeducedType_a = void (*)(int) noexcept;28 29void (*init_with_exact_type_b)(int) = redecl4<false>;30void (*init_with_mismatched_type_b)(int) noexcept = redecl4<false>; // expected-error {{cannot initialize a variable of type}}31auto deduce_auto_from_noexcept_function_ptr_b = redecl4<false>;32using DeducedType_b = decltype(deduce_auto_from_noexcept_function_ptr_b);33using DeducedType_b = void (*)(int);34 35static_assert(noexcept(init_with_exact_type_a(0)));36static_assert(noexcept((+init_with_exact_type_a)(0)));37static_assert(!noexcept(init_with_exact_type_b(0)));38static_assert(!noexcept((+init_with_exact_type_b)(0)));39 40// Don't look through casts, use the direct type of the expression.41// FIXME: static_cast here would be reasonable, but is not currently permitted.42static_assert(noexcept(static_cast<decltype(init_with_exact_type_a)>(init_with_exact_type_b)(0))); // expected-error {{is not allowed}}43static_assert(noexcept(reinterpret_cast<decltype(init_with_exact_type_a)>(init_with_exact_type_b)(0)));44static_assert(!noexcept(static_cast<decltype(init_with_exact_type_b)>(init_with_exact_type_a)(0)));45 46template<bool B> auto get_fn() noexcept -> void (*)() noexcept(B) {}47static_assert(noexcept(get_fn<true>()()));48static_assert(!noexcept(get_fn<false>()()));49 50namespace DependentDefaultCtorExceptionSpec {51  template<typename> struct T { static const bool value = true; };52 53  template<class A> struct map {54    typedef A a;55    map() noexcept(T<a>::value) {}56  };57 58  template<class B> struct multimap {59    typedef B b;60    multimap() noexcept(T<b>::value) {}61  };62 63  // Don't crash here.64  struct A { multimap<int> Map; } a;65 66  static_assert(noexcept(A()));67 68  template <class> struct NoexceptWithThis {69    int ca;70    template <class T> auto foo(T) noexcept(ca) { return true; }71    // expected-error@-1 {{noexcept specifier argument is not a constant expression}}72    // expected-note@-2 {{in instantiation of exception specification}}73    // expected-note@-3 {{implicit use of 'this' pointer is only allowed within the evaluation of a call to a 'constexpr' member function}}74  };75  struct InstantiateFromAnotherClass {76    template <class B, class T = decltype(static_cast<bool (B::*)(int)>(&B::foo))> // expected-note {{in instantiation of function template specialization}}77    InstantiateFromAnotherClass(B *) {} // expected-note {{in instantiation of default argument}}78  };79  NoexceptWithThis<int> f{};80  // Don't crash here.81  InstantiateFromAnotherClass b{&f}; // expected-note {{while substituting deduced template arguments into function template}}82}83 84#endif85 86namespace CompatWarning {87  struct X;88 89  // These cases don't change.90  void f0(void p() throw(int));91  auto f0() -> void (*)() noexcept(false);92 93  // These cases take an ABI break in C++17 because their parameter / return types change.94  void f1(void p() noexcept);95  void f2(void (*p)() noexcept(true));96  void f3(void (&p)() throw());97  void f4(void (X::*p)() throw());98  auto f5() -> void (*)() throw();99  auto f6() -> void (&)() throw();100  auto f7() -> void (X::*)() throw();101#if __cplusplus <= 201402L && !defined(NO_COMPAT_MANGLING)102  // expected-warning@-8 {{mangled name of 'f1' will change in C++17 due to non-throwing exception specification in function signature}}103  // expected-warning@-8 {{mangled name of 'f2' will change in C++17 due to non-throwing exception specification in function signature}}104  // expected-warning@-8 {{mangled name of 'f3' will change in C++17 due to non-throwing exception specification in function signature}}105  // expected-warning@-8 {{mangled name of 'f4' will change in C++17 due to non-throwing exception specification in function signature}}106  // expected-warning@-8 {{mangled name of 'f5' will change in C++17 due to non-throwing exception specification in function signature}}107  // expected-warning@-8 {{mangled name of 'f6' will change in C++17 due to non-throwing exception specification in function signature}}108  // expected-warning@-8 {{mangled name of 'f7' will change in C++17 due to non-throwing exception specification in function signature}}109#endif110 111  // An instantiation-dependent exception specification needs to be mangled in112  // all language modes, since it participates in SFINAE.113  template<typename T> void g(void() throw(T)); // expected-note {{substitution failure}}114  template<typename T> void g(...) = delete; // expected-note {{deleted}}115  void test_g() { g<void>(nullptr); } // expected-error {{deleted}}116 117  // An instantiation-dependent exception specification needs to be mangled in118  // all language modes, since it participates in SFINAE.119  template<typename T> void h(void() noexcept(T())); // expected-note {{substitution failure}}120  template<typename T> void h(...) = delete; // expected-note {{deleted}}121  void test_h() { h<void>(nullptr); } // expected-error {{deleted}}122}123 124namespace ImplicitExceptionSpec {125  struct S {126    ~S();127    void f(const S &s = S());128  };129  S::~S() {}130}131 132namespace Builtins {133  // Pick two functions that ought to have the same noexceptness.134  extern "C" int strcmp(const char *, const char *);135  extern "C" int strncmp(const char *, const char *, decltype(sizeof(0))) noexcept;136 137  // Check we recognized both as builtins.138  typedef int arr[strcmp("bar", "foo") + 4 * strncmp("foo", "bar", 4)]; // expected-warning {{variable length array folded to constant array as an extension}} \139                                                                           expected-warning {{variable length arrays in C++ are a Clang extension}} \140                                                                           expected-note {{non-constexpr function 'strcmp' cannot be used in a constant expression}}141  typedef int arr[3];142}143 144namespace ExplicitInstantiation {145  template<typename T> void f() noexcept {}146  template<typename T> struct X { void f() noexcept {} };147  template void f<int>();148  template void X<int>::f();149}150 151namespace ConversionFunction {152  struct A { template<typename T> operator T() noexcept; };153  int a = A().operator int();154}155 156using size_t = decltype(sizeof(0));157 158namespace OperatorDelete {159  struct W {};160  struct X {};161  struct Y {};162  struct Z {};163  template<bool N, bool D> struct T {};164}165void *operator new(size_t, OperatorDelete::W) noexcept(false);166void operator delete(void*, OperatorDelete::W) noexcept(false) = delete; // expected-note {{here}}167void *operator new(size_t, OperatorDelete::X) noexcept(false);168void operator delete(void*, OperatorDelete::X) noexcept(true) = delete; // expected-note {{here}}169void *operator new(size_t, OperatorDelete::Y) noexcept(true);170void operator delete(void*, OperatorDelete::Y) noexcept(false) = delete; // expected-note {{here}}171void *operator new(size_t, OperatorDelete::Z) noexcept(true);172void operator delete(void*, OperatorDelete::Z) noexcept(true) = delete; // expected-note {{here}}173template<bool N, bool D> void *operator new(size_t, OperatorDelete::T<N, D>) noexcept(N);174template<bool N, bool D> void operator delete(void*, OperatorDelete::T<N, D>) noexcept(D) = delete; // expected-note 4{{here}}175namespace OperatorDelete {176  struct A { A(); };177  A *w = new (W{}) A; // expected-error {{deleted function}}178  A *x = new (X{}) A; // expected-error {{deleted function}}179  A *y = new (Y{}) A; // expected-error {{deleted function}}180  A *z = new (Z{}) A; // expected-error {{deleted function}}181 182  A *t00 = new (T<false, false>{}) A; // expected-error {{deleted function}}183  A *t01 = new (T<false, true>{}) A; // expected-error {{deleted function}}184  A *t10 = new (T<true, false>{}) A; // expected-error {{deleted function}}185  A *t11 = new (T<true, true>{}) A; // expected-error {{deleted function}}186}187