xref: /llvm-project/clang/test/CXX/conv/conv.fctptr/p1.cpp (revision 15f3cd6bfc670ba6106184a903eb04be059e5977)
1e04c253aSNAKAMURA Takumi // RUN: %clang_cc1 -std=c++1z -verify %s -triple x86_64-unknown-unknown
23c4f8d2eSRichard Smith 
33c4f8d2eSRichard Smith struct S;
43c4f8d2eSRichard Smith 
53c4f8d2eSRichard Smith typedef void Nothrow() noexcept;
63c4f8d2eSRichard Smith typedef void Throw();
73c4f8d2eSRichard Smith 
83c4f8d2eSRichard Smith Nothrow *a;
93c4f8d2eSRichard Smith Throw *b;
103c4f8d2eSRichard Smith Nothrow S::*c;
113c4f8d2eSRichard Smith Throw S::*d;
123c4f8d2eSRichard Smith 
test()133c4f8d2eSRichard Smith void test() {
14fa755d3eSAnastasia Stulova   a = b; // expected-error {{incompatible function pointer types assigning to 'Nothrow *' (aka 'void (*)() noexcept') from 'Throw *' (aka 'void (*)()')}}
153c4f8d2eSRichard Smith   b = a;
163c4f8d2eSRichard Smith   c = d; // expected-error {{assigning to 'Nothrow S::*' from incompatible type 'Throw S::*': different exception specifications}}
173c4f8d2eSRichard Smith   d = c;
183c4f8d2eSRichard Smith 
193c4f8d2eSRichard Smith   // Function pointer conversions do not combine properly with qualification conversions.
203c4f8d2eSRichard Smith   // FIXME: This seems like a defect.
213c4f8d2eSRichard Smith   Nothrow *const *pa = b; // expected-error {{cannot initialize}}
223c4f8d2eSRichard Smith   Throw *const *pb = a; // expected-error {{cannot initialize}}
233c4f8d2eSRichard Smith   Nothrow *const S::*pc = d; // expected-error {{cannot initialize}}
243c4f8d2eSRichard Smith   Throw *const S::*pd = c; // expected-error {{cannot initialize}}
253c4f8d2eSRichard Smith }
263c4f8d2eSRichard Smith 
273c4f8d2eSRichard Smith // ... The result is a pointer to the function.
283c4f8d2eSRichard Smith void f() noexcept;
293c4f8d2eSRichard Smith constexpr void (*p)() = &f;
303c4f8d2eSRichard Smith static_assert(f == p);
313c4f8d2eSRichard Smith 
323c4f8d2eSRichard Smith struct S { void f() noexcept; };
333c4f8d2eSRichard Smith constexpr void (S::*q)() = &S::f;
343c4f8d2eSRichard Smith static_assert(q == &S::f);
353c4f8d2eSRichard Smith 
363c4f8d2eSRichard Smith 
373c4f8d2eSRichard Smith namespace std_example {
3882da19ddSRichard Smith   void (*p)();
3982da19ddSRichard Smith   void (**pp)() noexcept = &p; // expected-error {{cannot initialize a variable of type 'void (**)() noexcept' with an rvalue of type 'void (**)()'}}
403c4f8d2eSRichard Smith 
413c4f8d2eSRichard Smith   struct S { typedef void (*p)(); operator p(); }; // expected-note {{candidate}}
42*15f3cd6bSMatheus Izvekov   void (*q)() noexcept = S(); // expected-error {{no viable conversion from 'S' to 'void (*)() noexcept'}}
433c4f8d2eSRichard Smith }
44