xref: /llvm-project/clang/test/SemaCXX/unaddressable-functions.cpp (revision beca4a3338ab39dcdc81924734e95863fb53e5bb)
13cde9bf9SGeorge Burgess IV // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14
23cde9bf9SGeorge Burgess IV 
33cde9bf9SGeorge Burgess IV namespace access_control {
43cde9bf9SGeorge Burgess IV class Private {
53cde9bf9SGeorge Burgess IV   void check(int *) __attribute__((enable_if(false, "")));
63cde9bf9SGeorge Burgess IV   void check(double *) __attribute__((enable_if(true, "")));
73cde9bf9SGeorge Burgess IV 
83cde9bf9SGeorge Burgess IV   static void checkStatic(int *) __attribute__((enable_if(false, "")));
93cde9bf9SGeorge Burgess IV   static void checkStatic(double *) __attribute__((enable_if(true, "")));
103cde9bf9SGeorge Burgess IV };
113cde9bf9SGeorge Burgess IV 
123cde9bf9SGeorge Burgess IV auto Priv = reinterpret_cast<void (Private::*)(char *)>(&Private::check); // expected-error{{'check' is a private member of 'access_control::Private'}} expected-note@6{{implicitly declared private here}}
133cde9bf9SGeorge Burgess IV 
143cde9bf9SGeorge Burgess IV auto PrivStatic = reinterpret_cast<void (*)(char *)>(&Private::checkStatic); // expected-error{{'checkStatic' is a private member of 'access_control::Private'}} expected-note@9{{implicitly declared private here}}
153cde9bf9SGeorge Burgess IV 
163cde9bf9SGeorge Burgess IV class Protected {
173cde9bf9SGeorge Burgess IV protected:
183cde9bf9SGeorge Burgess IV   void check(int *) __attribute__((enable_if(false, "")));
193cde9bf9SGeorge Burgess IV   void check(double *) __attribute__((enable_if(true, "")));
203cde9bf9SGeorge Burgess IV 
213cde9bf9SGeorge Burgess IV   static void checkStatic(int *) __attribute__((enable_if(false, "")));
223cde9bf9SGeorge Burgess IV   static void checkStatic(double *) __attribute__((enable_if(true, "")));
233cde9bf9SGeorge Burgess IV };
243cde9bf9SGeorge Burgess IV 
253cde9bf9SGeorge Burgess IV auto Prot = reinterpret_cast<void (Protected::*)(char *)>(&Protected::check); // expected-error{{'check' is a protected member of 'access_control::Protected'}} expected-note@19{{declared protected here}}
263cde9bf9SGeorge Burgess IV 
273cde9bf9SGeorge Burgess IV auto ProtStatic = reinterpret_cast<void (*)(char *)>(&Protected::checkStatic); // expected-error{{'checkStatic' is a protected member of 'access_control::Protected'}} expected-note@22{{declared protected here}}
283cde9bf9SGeorge Burgess IV }
293cde9bf9SGeorge Burgess IV 
303cde9bf9SGeorge Burgess IV namespace unavailable {
313cde9bf9SGeorge Burgess IV // Ensure that we check that the function can be called
323cde9bf9SGeorge Burgess IV void foo() __attribute__((unavailable("don't call this")));
333cde9bf9SGeorge Burgess IV void foo(int) __attribute__((enable_if(false, "")));
343cde9bf9SGeorge Burgess IV 
353cde9bf9SGeorge Burgess IV void *Ptr = reinterpret_cast<void*>(foo); // expected-error{{'foo' is unavailable: don't call this}} expected-note@-3{{explicitly marked unavailable here}}
363cde9bf9SGeorge Burgess IV }
37cc2f355fSGeorge Burgess IV 
38cc2f355fSGeorge Burgess IV namespace template_deduction {
39cc2f355fSGeorge Burgess IV void foo() __attribute__((enable_if(false, "")));
40cc2f355fSGeorge Burgess IV 
41cc2f355fSGeorge Burgess IV void bar() __attribute__((enable_if(true, "")));
42cc2f355fSGeorge Burgess IV void bar() __attribute__((enable_if(false, "")));
43cc2f355fSGeorge Burgess IV 
44cc2f355fSGeorge Burgess IV void baz(int a) __attribute__((enable_if(true, "")));
45cc2f355fSGeorge Burgess IV void baz(int a) __attribute__((enable_if(a, "")));
46cc2f355fSGeorge Burgess IV void baz(int a) __attribute__((enable_if(false, "")));
47cc2f355fSGeorge Burgess IV 
48cc2f355fSGeorge Burgess IV void qux(int a) __attribute__((enable_if(1, "")));
49cc2f355fSGeorge Burgess IV void qux(int a) __attribute__((enable_if(true, "")));
50cc2f355fSGeorge Burgess IV void qux(int a) __attribute__((enable_if(a, "")));
51cc2f355fSGeorge Burgess IV void qux(int a) __attribute__((enable_if(false, "")));
52cc2f355fSGeorge Burgess IV 
call(Fn F,Args...As)53cc2f355fSGeorge Burgess IV template <typename Fn, typename... Args> void call(Fn F, Args... As) {
54cc2f355fSGeorge Burgess IV   F(As...);
55cc2f355fSGeorge Burgess IV }
56cc2f355fSGeorge Burgess IV 
test()57cc2f355fSGeorge Burgess IV void test() {
58cc2f355fSGeorge Burgess IV   call(foo); // expected-error{{cannot take address of function 'foo'}}
59cc2f355fSGeorge Burgess IV   call(bar);
60cc2f355fSGeorge Burgess IV   call(baz, 0);
61cc2f355fSGeorge Burgess IV   call(qux, 0); // expected-error{{no matching function for call to 'call'}} expected-note@53{{candidate template ignored: couldn't infer template argument 'Fn'}}
62cc2f355fSGeorge Burgess IV 
63cc2f355fSGeorge Burgess IV   auto Ptr1 = foo; // expected-error{{cannot take address of function 'foo'}}
64cc2f355fSGeorge Burgess IV   auto Ptr2 = bar;
65cc2f355fSGeorge Burgess IV   auto Ptr3 = baz;
66cc2f355fSGeorge Burgess IV   auto Ptr4 = qux; // expected-error{{variable 'Ptr4' with type 'auto' has incompatible initializer of type '<overloaded function type>'}}
67cc2f355fSGeorge Burgess IV }
68cc2f355fSGeorge Burgess IV 
69cc2f355fSGeorge Burgess IV template <typename Fn, typename T, typename... Args>
callMem(Fn F,T t,Args...As)70cc2f355fSGeorge Burgess IV void callMem(Fn F, T t, Args... As) {
71cc2f355fSGeorge Burgess IV   (t.*F)(As...);
72cc2f355fSGeorge Burgess IV }
73cc2f355fSGeorge Burgess IV 
74cc2f355fSGeorge Burgess IV class Foo {
75cc2f355fSGeorge Burgess IV   void bar() __attribute__((enable_if(true, "")));
76cc2f355fSGeorge Burgess IV   void bar() __attribute__((enable_if(false, "")));
77cc2f355fSGeorge Burgess IV 
78cc2f355fSGeorge Burgess IV   static void staticBar() __attribute__((enable_if(true, "")));
79cc2f355fSGeorge Burgess IV   static void staticBar() __attribute__((enable_if(false, "")));
80cc2f355fSGeorge Burgess IV };
81cc2f355fSGeorge Burgess IV 
testAccess()82cc2f355fSGeorge Burgess IV void testAccess() {
83cc2f355fSGeorge Burgess IV   callMem(&Foo::bar, Foo()); // expected-error{{'bar' is a private member of 'template_deduction::Foo'}} expected-note@-8{{implicitly declared private here}}
84cc2f355fSGeorge Burgess IV   call(&Foo::staticBar); // expected-error{{'staticBar' is a private member of 'template_deduction::Foo'}} expected-note@-6{{implicitly declared private here}}
85cc2f355fSGeorge Burgess IV }
86cc2f355fSGeorge Burgess IV }
87cc2f355fSGeorge Burgess IV 
88cc2f355fSGeorge Burgess IV namespace template_template_deduction {
89cc2f355fSGeorge Burgess IV void foo() __attribute__((enable_if(false, "")));
90cc2f355fSGeorge Burgess IV template <typename T>
91cc2f355fSGeorge Burgess IV T foo() __attribute__((enable_if(true, "")));
92cc2f355fSGeorge Burgess IV 
call(Fn F,Args...As)93cc2f355fSGeorge Burgess IV template <typename Fn, typename... Args> auto call(Fn F, Args... As) {
94cc2f355fSGeorge Burgess IV   return F(As...);
95cc2f355fSGeorge Burgess IV }
96cc2f355fSGeorge Burgess IV 
97cc2f355fSGeorge Burgess IV auto Ok = call(&foo<int>);
98cc2f355fSGeorge Burgess IV auto Fail = call(&foo); // expected-error{{no matching function for call to 'call'}} expected-note@-5{{candidate template ignored: couldn't infer template argument 'Fn'}}
99cc2f355fSGeorge Burgess IV 
100cc2f355fSGeorge Burgess IV auto PtrOk = &foo<int>;
101cc2f355fSGeorge Burgess IV auto PtrFail = &foo; // expected-error{{variable 'PtrFail' with type 'auto' has incompatible initializer of type '<overloaded function type>'}}
102cc2f355fSGeorge Burgess IV }
103*beca4a33SGeorge Burgess IV 
104*beca4a33SGeorge Burgess IV namespace pointer_equality {
105*beca4a33SGeorge Burgess IV   using FnTy = void (*)();
106*beca4a33SGeorge Burgess IV 
107*beca4a33SGeorge Burgess IV   void bothEnableIf() __attribute__((enable_if(false, "")));
108*beca4a33SGeorge Burgess IV   void bothEnableIf() __attribute__((enable_if(true, "")));
109*beca4a33SGeorge Burgess IV 
110*beca4a33SGeorge Burgess IV   void oneEnableIf() __attribute__((enable_if(false, "")));
111*beca4a33SGeorge Burgess IV   void oneEnableIf();
112*beca4a33SGeorge Burgess IV 
test()113*beca4a33SGeorge Burgess IV   void test() {
114*beca4a33SGeorge Burgess IV     FnTy Fn;
115*beca4a33SGeorge Burgess IV     (void)(Fn == bothEnableIf);
116*beca4a33SGeorge Burgess IV     (void)(Fn == &bothEnableIf);
117*beca4a33SGeorge Burgess IV     (void)(Fn == oneEnableIf);
118*beca4a33SGeorge Burgess IV     (void)(Fn == &oneEnableIf);
119*beca4a33SGeorge Burgess IV   }
120*beca4a33SGeorge Burgess IV 
121*beca4a33SGeorge Burgess IV   void unavailableEnableIf() __attribute__((enable_if(false, "")));
122*beca4a33SGeorge Burgess IV   void unavailableEnableIf() __attribute__((unavailable("noooo"))); // expected-note 2{{marked unavailable here}}
123*beca4a33SGeorge Burgess IV 
testUnavailable()124*beca4a33SGeorge Burgess IV   void testUnavailable() {
125*beca4a33SGeorge Burgess IV     FnTy Fn;
126*beca4a33SGeorge Burgess IV     (void)(Fn == unavailableEnableIf); // expected-error{{is unavailable}}
127*beca4a33SGeorge Burgess IV     (void)(Fn == &unavailableEnableIf); // expected-error{{is unavailable}}
128*beca4a33SGeorge Burgess IV   }
129*beca4a33SGeorge Burgess IV 
130*beca4a33SGeorge Burgess IV   class Foo {
131*beca4a33SGeorge Burgess IV     static void staticAccessEnableIf(); // expected-note 2{{declared private here}}
132*beca4a33SGeorge Burgess IV     void accessEnableIf(); // expected-note{{declared private here}}
133*beca4a33SGeorge Burgess IV 
134*beca4a33SGeorge Burgess IV   public:
135*beca4a33SGeorge Burgess IV     static void staticAccessEnableIf() __attribute__((enable_if(false, "")));
136*beca4a33SGeorge Burgess IV     void accessEnableIf() __attribute__((enable_if(false, "")));
137*beca4a33SGeorge Burgess IV   };
138*beca4a33SGeorge Burgess IV 
testAccess()139*beca4a33SGeorge Burgess IV   void testAccess() {
140*beca4a33SGeorge Burgess IV     FnTy Fn;
141*beca4a33SGeorge Burgess IV     (void)(Fn == Foo::staticAccessEnableIf); // expected-error{{is a private member}}
142*beca4a33SGeorge Burgess IV     (void)(Fn == &Foo::staticAccessEnableIf); // expected-error{{is a private member}}
143*beca4a33SGeorge Burgess IV 
144*beca4a33SGeorge Burgess IV     void (Foo::*MemFn)();
145*beca4a33SGeorge Burgess IV     (void)(MemFn == &Foo::accessEnableIf); // expected-error{{is a private member}}
146*beca4a33SGeorge Burgess IV   }
147*beca4a33SGeorge Burgess IV }
148