1*1be59c51SRichard Smith // RUN: %clang_cc1 -fsyntax-only -DNOEXCEPT= -verify %s
2*1be59c51SRichard Smith // RUN: %clang_cc1 -fsyntax-only -std=c++1z -DNOEXCEPT= -verify %s
3*1be59c51SRichard Smith // RUN: %clang_cc1 -fsyntax-only -std=c++1z -DNOEXCEPT=noexcept -verify %s
46b6ba8baSDouglas Gregor
53c4f8d2eSRichard Smith template<typename T> T f0(T) NOEXCEPT;
63c4f8d2eSRichard Smith int f0(int) NOEXCEPT;
76b6ba8baSDouglas Gregor
86b6ba8baSDouglas Gregor // -- an object or reference being initialized
96b6ba8baSDouglas Gregor struct S {
106b6ba8baSDouglas Gregor int (*f0)(int);
116b6ba8baSDouglas Gregor float (*f1)(float);
126b6ba8baSDouglas Gregor };
136b6ba8baSDouglas Gregor
test_init_f0()146b6ba8baSDouglas Gregor void test_init_f0() {
156b6ba8baSDouglas Gregor int (*f0a)(int) = f0;
166b6ba8baSDouglas Gregor int (*f0b)(int) = &f0;
176b6ba8baSDouglas Gregor int (*f0c)(int) = (f0);
186b6ba8baSDouglas Gregor float (*f0d)(float) = f0;
196b6ba8baSDouglas Gregor float (*f0e)(float) = &f0;
206b6ba8baSDouglas Gregor float (*f0f)(float) = (f0);
216b6ba8baSDouglas Gregor int (&f0g)(int) = f0;
226b6ba8baSDouglas Gregor int (&f0h)(int) = (f0);
236b6ba8baSDouglas Gregor float (&f0i)(float) = f0;
24631a57e3SDaniel Dunbar float (&f0j)(float) = (f0);
256b6ba8baSDouglas Gregor S s = { f0, f0 };
266b6ba8baSDouglas Gregor }
276b6ba8baSDouglas Gregor
286b6ba8baSDouglas Gregor // -- the left side of an assignment (5.17),
test_assign_f0()296b6ba8baSDouglas Gregor void test_assign_f0() {
306b6ba8baSDouglas Gregor int (*f0a)(int) = 0;
316b6ba8baSDouglas Gregor float (*f0b)(float) = 0;
326b6ba8baSDouglas Gregor
336b6ba8baSDouglas Gregor f0a = f0;
346b6ba8baSDouglas Gregor f0a = &f0;
356b6ba8baSDouglas Gregor f0a = (f0);
366b6ba8baSDouglas Gregor f0b = f0;
376b6ba8baSDouglas Gregor f0b = &f0;
386b6ba8baSDouglas Gregor f0b = (f0);
396b6ba8baSDouglas Gregor }
406b6ba8baSDouglas Gregor
416b6ba8baSDouglas Gregor // -- a parameter of a function (5.2.2),
426b6ba8baSDouglas Gregor void eat_f0(int a(int), float (*b)(float), int (&c)(int), float (&d)(float));
436b6ba8baSDouglas Gregor
test_pass_f0()446b6ba8baSDouglas Gregor void test_pass_f0() {
456b6ba8baSDouglas Gregor eat_f0(f0, f0, f0, f0);
466b6ba8baSDouglas Gregor eat_f0(&f0, &f0, (f0), (f0));
476b6ba8baSDouglas Gregor }
486b6ba8baSDouglas Gregor
496b6ba8baSDouglas Gregor // -- a parameter of a user-defined operator (13.5),
506b6ba8baSDouglas Gregor struct X { };
516b6ba8baSDouglas Gregor void operator+(X, int(int));
526b6ba8baSDouglas Gregor void operator-(X, float(*)(float));
536b6ba8baSDouglas Gregor void operator*(X, int (&)(int));
546b6ba8baSDouglas Gregor void operator/(X, float (&)(float));
556b6ba8baSDouglas Gregor
test_operator_pass_f0(X x)566b6ba8baSDouglas Gregor void test_operator_pass_f0(X x) {
576b6ba8baSDouglas Gregor x + f0;
586b6ba8baSDouglas Gregor x + &f0;
596b6ba8baSDouglas Gregor x - f0;
606b6ba8baSDouglas Gregor x - &f0;
616b6ba8baSDouglas Gregor x * f0;
626b6ba8baSDouglas Gregor x * (f0);
636b6ba8baSDouglas Gregor x / f0;
646b6ba8baSDouglas Gregor x / (f0);
656b6ba8baSDouglas Gregor }
666b6ba8baSDouglas Gregor
676b6ba8baSDouglas Gregor // -- the return value of a function, operator function, or conversion (6.6.3),
test_return_f0_a()686b6ba8baSDouglas Gregor int (*test_return_f0_a())(int) { return f0; }
test_return_f0_b()696b6ba8baSDouglas Gregor int (*test_return_f0_b())(int) { return &f0; }
test_return_f0_c()706b6ba8baSDouglas Gregor int (*test_return_f0_c())(int) { return (f0); }
test_return_f0_d()716b6ba8baSDouglas Gregor float (*test_return_f0_d())(float) { return f0; }
test_return_f0_e()726b6ba8baSDouglas Gregor float (*test_return_f0_e())(float) { return &f0; }
test_return_f0_f()736b6ba8baSDouglas Gregor float (*test_return_f0_f())(float) { return (f0); }
746b6ba8baSDouglas Gregor
756b6ba8baSDouglas Gregor // -- an explicit type conversion (5.2.3, 5.2.9, 5.4), or
test_convert_f0()766b6ba8baSDouglas Gregor void test_convert_f0() {
776b6ba8baSDouglas Gregor (void)((int (*)(int))f0);
786b6ba8baSDouglas Gregor (void)((int (*)(int))&f0);
796b6ba8baSDouglas Gregor (void)((int (*)(int))(f0));
806b6ba8baSDouglas Gregor (void)((float (*)(float))f0);
816b6ba8baSDouglas Gregor (void)((float (*)(float))&f0);
826b6ba8baSDouglas Gregor (void)((float (*)(float))(f0));
836b6ba8baSDouglas Gregor }
846b6ba8baSDouglas Gregor
856b6ba8baSDouglas Gregor // -- a non-type template-parameter(14.3.2).
866b6ba8baSDouglas Gregor template<int(int)> struct Y0 { };
876b6ba8baSDouglas Gregor template<float(float)> struct Y1 { };
886b6ba8baSDouglas Gregor template<int (&)(int)> struct Y2 { };
896b6ba8baSDouglas Gregor template<float (&)(float)> struct Y3 { };
906b6ba8baSDouglas Gregor
916b6ba8baSDouglas Gregor Y0<f0> y0;
926b6ba8baSDouglas Gregor Y0<&f0> y0a;
936b6ba8baSDouglas Gregor Y1<f0> y1;
946b6ba8baSDouglas Gregor Y1<&f0> y1a;
956b6ba8baSDouglas Gregor Y2<f0> y2;
966b6ba8baSDouglas Gregor Y3<f0> y3;
97*1be59c51SRichard Smith
98*1be59c51SRichard Smith #if __cplusplus > 201402L
99*1be59c51SRichard Smith namespace MixedNoexcept {
100*1be59c51SRichard Smith inline namespace A {
101*1be59c51SRichard Smith void f() noexcept; // expected-note {{candidate}}
102*1be59c51SRichard Smith }
103*1be59c51SRichard Smith inline namespace B {
104*1be59c51SRichard Smith void f(); // expected-note {{candidate}}
105*1be59c51SRichard Smith }
106*1be59c51SRichard Smith void (*p)() noexcept = &f; // ok
107*1be59c51SRichard Smith void (*q)() = &f; // expected-error {{ambiguous}}
108*1be59c51SRichard Smith }
109*1be59c51SRichard Smith #else
110*1be59c51SRichard Smith // expected-no-diagnostics
111*1be59c51SRichard Smith #endif
112