1 | // RUN: %clang_cc1 -fsyntax-only -DNOEXCEPT= -verify %s |
2 | // RUN: %clang_cc1 -fsyntax-only -std=c++1z -DNOEXCEPT= -verify %s |
3 | // RUN: %clang_cc1 -fsyntax-only -std=c++1z -DNOEXCEPT=noexcept -verify %s |
4 | |
5 | template<typename T> T f0(T) NOEXCEPT; |
6 | int f0(int) NOEXCEPT; |
7 | |
8 | // -- an object or reference being initialized |
9 | struct S { |
10 | int (*f0)(int); |
11 | float (*f1)(float); |
12 | }; |
13 | |
14 | void test_init_f0() { |
15 | int (*f0a)(int) = f0; |
16 | int (*f0b)(int) = &f0; |
17 | int (*f0c)(int) = (f0); |
18 | float (*f0d)(float) = f0; |
19 | float (*f0e)(float) = &f0; |
20 | float (*f0f)(float) = (f0); |
21 | int (&f0g)(int) = f0; |
22 | int (&f0h)(int) = (f0); |
23 | float (&f0i)(float) = f0; |
24 | float (&f0j)(float) = (f0); |
25 | S s = { f0, f0 }; |
26 | } |
27 | |
28 | // -- the left side of an assignment (5.17), |
29 | void test_assign_f0() { |
30 | int (*f0a)(int) = 0; |
31 | float (*f0b)(float) = 0; |
32 | |
33 | f0a = f0; |
34 | f0a = &f0; |
35 | f0a = (f0); |
36 | f0b = f0; |
37 | f0b = &f0; |
38 | f0b = (f0); |
39 | } |
40 | |
41 | // -- a parameter of a function (5.2.2), |
42 | void eat_f0(int a(int), float (*b)(float), int (&c)(int), float (&d)(float)); |
43 | |
44 | void test_pass_f0() { |
45 | eat_f0(f0, f0, f0, f0); |
46 | eat_f0(&f0, &f0, (f0), (f0)); |
47 | } |
48 | |
49 | // -- a parameter of a user-defined operator (13.5), |
50 | struct X { }; |
51 | void operator+(X, int(int)); |
52 | void operator-(X, float(*)(float)); |
53 | void operator*(X, int (&)(int)); |
54 | void operator/(X, float (&)(float)); |
55 | |
56 | void test_operator_pass_f0(X x) { |
57 | x + f0; |
58 | x + &f0; |
59 | x - f0; |
60 | x - &f0; |
61 | x * f0; |
62 | x * (f0); |
63 | x / f0; |
64 | x / (f0); |
65 | } |
66 | |
67 | // -- the return value of a function, operator function, or conversion (6.6.3), |
68 | int (*test_return_f0_a())(int) { return f0; } |
69 | int (*test_return_f0_b())(int) { return &f0; } |
70 | int (*test_return_f0_c())(int) { return (f0); } |
71 | float (*test_return_f0_d())(float) { return f0; } |
72 | float (*test_return_f0_e())(float) { return &f0; } |
73 | float (*test_return_f0_f())(float) { return (f0); } |
74 | |
75 | // -- an explicit type conversion (5.2.3, 5.2.9, 5.4), or |
76 | void test_convert_f0() { |
77 | (void)((int (*)(int))f0); |
78 | (void)((int (*)(int))&f0); |
79 | (void)((int (*)(int))(f0)); |
80 | (void)((float (*)(float))f0); |
81 | (void)((float (*)(float))&f0); |
82 | (void)((float (*)(float))(f0)); |
83 | } |
84 | |
85 | // -- a non-type template-parameter(14.3.2). |
86 | template<int(int)> struct Y0 { }; |
87 | template<float(float)> struct Y1 { }; |
88 | template<int (&)(int)> struct Y2 { }; |
89 | template<float (&)(float)> struct Y3 { }; |
90 | |
91 | Y0<f0> y0; |
92 | Y0<&f0> y0a; |
93 | Y1<f0> y1; |
94 | Y1<&f0> y1a; |
95 | Y2<f0> y2; |
96 | Y3<f0> y3; |
97 | |
98 | #if __cplusplus > 201402L |
99 | namespace MixedNoexcept { |
100 | inline namespace A { |
101 | void f() noexcept; // expected-note {{candidate}} |
102 | } |
103 | inline namespace B { |
104 | void f(); // expected-note {{candidate}} |
105 | } |
106 | void (*p)() noexcept = &f; // ok |
107 | void (*q)() = &f; // expected-error {{ambiguous}} |
108 | } |
109 | #else |
110 | // expected-no-diagnostics |
111 | #endif |
112 | |