1 | // RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14 |
2 | |
3 | namespace access_control { |
4 | class Private { |
5 | void check(int *) __attribute__((enable_if(false, ""))); |
6 | void check(double *) __attribute__((enable_if(true, ""))); |
7 | |
8 | static void checkStatic(int *) __attribute__((enable_if(false, ""))); |
9 | static void checkStatic(double *) __attribute__((enable_if(true, ""))); |
10 | }; |
11 | |
12 | 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}} |
13 | |
14 | 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}} |
15 | |
16 | class Protected { |
17 | protected: |
18 | void check(int *) __attribute__((enable_if(false, ""))); |
19 | void check(double *) __attribute__((enable_if(true, ""))); |
20 | |
21 | static void checkStatic(int *) __attribute__((enable_if(false, ""))); |
22 | static void checkStatic(double *) __attribute__((enable_if(true, ""))); |
23 | }; |
24 | |
25 | 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}} |
26 | |
27 | 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}} |
28 | } |
29 | |
30 | namespace unavailable { |
31 | // Ensure that we check that the function can be called |
32 | void foo() __attribute__((unavailable("don't call this"))); |
33 | void foo(int) __attribute__((enable_if(false, ""))); |
34 | |
35 | void *Ptr = reinterpret_cast<void*>(foo); // expected-error{{'foo' is unavailable: don't call this}} expected-note@-3{{explicitly marked unavailable here}} |
36 | } |
37 | |
38 | namespace template_deduction { |
39 | void foo() __attribute__((enable_if(false, ""))); |
40 | |
41 | void bar() __attribute__((enable_if(true, ""))); |
42 | void bar() __attribute__((enable_if(false, ""))); |
43 | |
44 | void baz(int a) __attribute__((enable_if(true, ""))); |
45 | void baz(int a) __attribute__((enable_if(a, ""))); |
46 | void baz(int a) __attribute__((enable_if(false, ""))); |
47 | |
48 | void qux(int a) __attribute__((enable_if(1, ""))); |
49 | void qux(int a) __attribute__((enable_if(true, ""))); |
50 | void qux(int a) __attribute__((enable_if(a, ""))); |
51 | void qux(int a) __attribute__((enable_if(false, ""))); |
52 | |
53 | template <typename Fn, typename... Args> void call(Fn F, Args... As) { |
54 | F(As...); |
55 | } |
56 | |
57 | void test() { |
58 | call(foo); // expected-error{{cannot take address of function 'foo'}} |
59 | call(bar); |
60 | call(baz, 0); |
61 | call(qux, 0); // expected-error{{no matching function for call to 'call'}} expected-note@53{{candidate template ignored: couldn't infer template argument 'Fn'}} |
62 | |
63 | auto Ptr1 = foo; // expected-error{{cannot take address of function 'foo'}} |
64 | auto Ptr2 = bar; |
65 | auto Ptr3 = baz; |
66 | auto Ptr4 = qux; // expected-error{{variable 'Ptr4' with type 'auto' has incompatible initializer of type '<overloaded function type>'}} |
67 | } |
68 | |
69 | template <typename Fn, typename T, typename... Args> |
70 | void callMem(Fn F, T t, Args... As) { |
71 | (t.*F)(As...); |
72 | } |
73 | |
74 | class Foo { |
75 | void bar() __attribute__((enable_if(true, ""))); |
76 | void bar() __attribute__((enable_if(false, ""))); |
77 | |
78 | static void staticBar() __attribute__((enable_if(true, ""))); |
79 | static void staticBar() __attribute__((enable_if(false, ""))); |
80 | }; |
81 | |
82 | void testAccess() { |
83 | callMem(&Foo::bar, Foo()); // expected-error{{'bar' is a private member of 'template_deduction::Foo'}} expected-note@-8{{implicitly declared private here}} |
84 | call(&Foo::staticBar); // expected-error{{'staticBar' is a private member of 'template_deduction::Foo'}} expected-note@-6{{implicitly declared private here}} |
85 | } |
86 | } |
87 | |
88 | namespace template_template_deduction { |
89 | void foo() __attribute__((enable_if(false, ""))); |
90 | template <typename T> |
91 | T foo() __attribute__((enable_if(true, ""))); |
92 | |
93 | template <typename Fn, typename... Args> auto call(Fn F, Args... As) { |
94 | return F(As...); |
95 | } |
96 | |
97 | auto Ok = call(&foo<int>); |
98 | 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'}} |
99 | |
100 | auto PtrOk = &foo<int>; |
101 | auto PtrFail = &foo; // expected-error{{variable 'PtrFail' with type 'auto' has incompatible initializer of type '<overloaded function type>'}} |
102 | } |
103 | |
104 | namespace pointer_equality { |
105 | using FnTy = void (*)(); |
106 | |
107 | void bothEnableIf() __attribute__((enable_if(false, ""))); |
108 | void bothEnableIf() __attribute__((enable_if(true, ""))); |
109 | |
110 | void oneEnableIf() __attribute__((enable_if(false, ""))); |
111 | void oneEnableIf(); |
112 | |
113 | void test() { |
114 | FnTy Fn; |
115 | (void)(Fn == bothEnableIf); |
116 | (void)(Fn == &bothEnableIf); |
117 | (void)(Fn == oneEnableIf); |
118 | (void)(Fn == &oneEnableIf); |
119 | } |
120 | |
121 | void unavailableEnableIf() __attribute__((enable_if(false, ""))); |
122 | void unavailableEnableIf() __attribute__((unavailable("noooo"))); // expected-note 2{{marked unavailable here}} |
123 | |
124 | void testUnavailable() { |
125 | FnTy Fn; |
126 | (void)(Fn == unavailableEnableIf); // expected-error{{is unavailable}} |
127 | (void)(Fn == &unavailableEnableIf); // expected-error{{is unavailable}} |
128 | } |
129 | |
130 | class Foo { |
131 | static void staticAccessEnableIf(); // expected-note 2{{declared private here}} |
132 | void accessEnableIf(); // expected-note{{declared private here}} |
133 | |
134 | public: |
135 | static void staticAccessEnableIf() __attribute__((enable_if(false, ""))); |
136 | void accessEnableIf() __attribute__((enable_if(false, ""))); |
137 | }; |
138 | |
139 | void testAccess() { |
140 | FnTy Fn; |
141 | (void)(Fn == Foo::staticAccessEnableIf); // expected-error{{is a private member}} |
142 | (void)(Fn == &Foo::staticAccessEnableIf); // expected-error{{is a private member}} |
143 | |
144 | void (Foo::*MemFn)(); |
145 | (void)(MemFn == &Foo::accessEnableIf); // expected-error{{is a private member}} |
146 | } |
147 | } |
148 | |