1 // RUN: %clang_cc1 -std=c++1z -verify %s -fexceptions -fcxx-exceptions -Wno-dynamic-exception-spec
6 using A
= void (*)() noexcept
;
8 using C
= void (X::*)() noexcept
;
9 using D
= void (X::*)();
10 using E
= void (Y::*)() noexcept
;
11 using F
= void (Y::*)();
13 void f(A a
, B b
, C c
, D d
, E e
, F f
, bool k
) {
14 a
= k
? a
: b
; // expected-error {{incompatible function pointer types assigning to 'A' (aka 'void (*)() noexcept') from 'void (*)()'}}
17 c
= k
? c
: d
; // expected-error {{different exception specifications}}
20 e
= k
? c
: f
; // expected-error {{different exception specifications}}
21 e
= k
? d
: e
; // expected-error {{different exception specifications}}
27 const A
&ak2
= k
? ak
: ak
;
28 const A
&ak3
= k
? ak
: bk
; // expected-error {{could not bind}}
29 const B
&bk3
= k
? ak
: bk
;
32 namespace dynamic_exception_spec
{
33 // Prior to P0012, we had:
34 // "[...] the target entity shall allow at least the exceptions allowed
35 // by the source value in the assignment or initialization"
37 // There's really only one way we can coherently apply this to conditional
38 // expressions: this must hold no matter which branch was taken.
39 using X
= void (*)() throw(int);
40 using Y
= void (*)() throw(float);
41 using Z
= void (*)() throw(int, float);
42 void g(X x
, Y y
, Z z
, bool k
) {
43 x
= k
? X() : Y(); // expected-warning {{not superset}}
44 y
= k
? X() : Y(); // expected-warning {{not superset}}
47 x
= k
? x
: y
; // expected-warning {{not superset}}
48 y
= k
? x
: y
; // expected-warning {{not superset}}