]> granicus.if.org Git - clang/blob - test/SemaCXX/cxx1z-noexcept-function-type.cpp
[c++1z] PR31210: ignore exception specification when matching the type of a
[clang] / test / SemaCXX / cxx1z-noexcept-function-type.cpp
1 // RUN: %clang_cc1 -std=c++14 -verify %s
2 // RUN: %clang_cc1 -std=c++1z -verify %s
3
4 #if __cplusplus > 201402L
5
6 template<typename T> void redecl1() noexcept(noexcept(T())) {} // expected-note {{previous}}
7 template<typename T> void redecl1() noexcept(noexcept(T())); // ok, same type
8 template<typename T> void redecl1() noexcept(noexcept(T())) {} // expected-error {{redefinition}}
9
10 template<bool A, bool B> void redecl2() noexcept(A); // expected-note {{previous}}
11 template<bool A, bool B> void redecl2() noexcept(B); // expected-error {{conflicting types}}
12
13 // These have the same canonical type.
14 // FIXME: It's not clear whether this is supposed to be valid.
15 template<typename A, typename B> void redecl3() throw(A);
16 template<typename A, typename B> void redecl3() throw(B);
17
18 typedef int I;
19 template<bool B> void redecl4(I) noexcept(B);
20 template<bool B> void redecl4(I) noexcept(B); // expected-note {{failed template argument deduction}}
21
22 void (*init_with_exact_type_a)(int) noexcept = redecl4<true>;
23 void (*init_with_mismatched_type_a)(int) = redecl4<true>;
24 auto deduce_auto_from_noexcept_function_ptr_a = redecl4<true>;
25 using DeducedType_a = decltype(deduce_auto_from_noexcept_function_ptr_a);
26 using DeducedType_a = void (*)(int) noexcept;
27
28 void (*init_with_exact_type_b)(int) = redecl4<false>;
29 void (*init_with_mismatched_type_b)(int) noexcept = redecl4<false>; // expected-error {{does not match required type}}
30 auto deduce_auto_from_noexcept_function_ptr_b = redecl4<false>;
31 using DeducedType_b = decltype(deduce_auto_from_noexcept_function_ptr_b);
32 using DeducedType_b = void (*)(int);
33
34 namespace DependentDefaultCtorExceptionSpec {
35   template<typename> struct T { static const bool value = true; };
36
37   template<class A> struct map {
38     typedef A a;
39     map() noexcept(T<a>::value) {}
40   };
41
42   template<class B> struct multimap {
43     typedef B b;
44     multimap() noexcept(T<b>::value) {}
45   };
46
47   // Don't crash here.
48   struct A { multimap<int> Map; } a;
49
50   static_assert(noexcept(A()));
51 }
52
53 #endif
54
55 namespace CompatWarning {
56   struct X;
57
58   // These cases don't change.
59   void f0(void p() throw(int));
60   auto f0() -> void (*)() noexcept(false);
61
62   // These cases take an ABI break in C++17 because their parameter / return types change.
63   void f1(void p() noexcept);
64   void f2(void (*p)() noexcept(true));
65   void f3(void (&p)() throw());
66   void f4(void (X::*p)() throw());
67   auto f5() -> void (*)() throw();
68   auto f6() -> void (&)() throw();
69   auto f7() -> void (X::*)() throw();
70 #if __cplusplus <= 201402L
71   // expected-warning@-8 {{mangled name of 'f1' will change in C++17 due to non-throwing exception specification in function signature}}
72   // expected-warning@-8 {{mangled name of 'f2' will change in C++17 due to non-throwing exception specification in function signature}}
73   // expected-warning@-8 {{mangled name of 'f3' will change in C++17 due to non-throwing exception specification in function signature}}
74   // expected-warning@-8 {{mangled name of 'f4' will change in C++17 due to non-throwing exception specification in function signature}}
75   // expected-warning@-8 {{mangled name of 'f5' will change in C++17 due to non-throwing exception specification in function signature}}
76   // expected-warning@-8 {{mangled name of 'f6' will change in C++17 due to non-throwing exception specification in function signature}}
77   // expected-warning@-8 {{mangled name of 'f7' will change in C++17 due to non-throwing exception specification in function signature}}
78 #endif
79
80   // An instantiation-dependent exception specification needs to be mangled in
81   // all language modes, since it participates in SFINAE.
82   template<typename T> void g(void() throw(T)); // expected-note {{substitution failure}}
83   template<typename T> void g(...) = delete; // expected-note {{deleted}}
84   void test_g() { g<void>(nullptr); } // expected-error {{deleted}}
85
86   // An instantiation-dependent exception specification needs to be mangled in
87   // all language modes, since it participates in SFINAE.
88   template<typename T> void h(void() noexcept(T())); // expected-note {{substitution failure}}
89   template<typename T> void h(...) = delete; // expected-note {{deleted}}
90   void test_h() { h<void>(nullptr); } // expected-error {{deleted}}
91 }
92
93 namespace ImplicitExceptionSpec {
94   struct S {
95     ~S();
96     void f(const S &s = S());
97   };
98   S::~S() {}
99 }
100
101 namespace Builtins {
102   // Pick two functions that ought to have the same noexceptness.
103   extern "C" int strcmp(const char *, const char *);
104   extern "C" int strncmp(const char *, const char *, decltype(sizeof(0))) noexcept;
105
106   // Check we recognized both as builtins.
107   typedef int arr[strcmp("bar", "foo") + 4 * strncmp("foo", "bar", 4)];
108   typedef int arr[3];
109 }