summaryrefslogtreecommitdiffstats
path: root/clang/test/SemaCXX/unaddressable-functions.cpp
blob: 823f1be05f80c69e65066c3e57e7c83da1439e6a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// RUN: %clang_cc1 -fsyntax-only -verify %s -std=c++14

namespace access_control {
class Private {
  void check(int *) __attribute__((enable_if(false, "")));
  void check(double *) __attribute__((enable_if(true, "")));

  static void checkStatic(int *) __attribute__((enable_if(false, "")));
  static void checkStatic(double *) __attribute__((enable_if(true, "")));
};

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}}

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}}

class Protected {
protected:
  void check(int *) __attribute__((enable_if(false, "")));
  void check(double *) __attribute__((enable_if(true, "")));

  static void checkStatic(int *) __attribute__((enable_if(false, "")));
  static void checkStatic(double *) __attribute__((enable_if(true, "")));
};

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}}

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}}
}

namespace unavailable {
// Ensure that we check that the function can be called
void foo() __attribute__((unavailable("don't call this")));
void foo(int) __attribute__((enable_if(false, "")));

void *Ptr = reinterpret_cast<void*>(foo); // expected-error{{'foo' is unavailable: don't call this}} expected-note@-3{{explicitly marked unavailable here}}
}

namespace template_deduction {
void foo() __attribute__((enable_if(false, "")));

void bar() __attribute__((enable_if(true, "")));
void bar() __attribute__((enable_if(false, "")));

void baz(int a) __attribute__((enable_if(true, "")));
void baz(int a) __attribute__((enable_if(a, "")));
void baz(int a) __attribute__((enable_if(false, "")));

void qux(int a) __attribute__((enable_if(1, "")));
void qux(int a) __attribute__((enable_if(true, "")));
void qux(int a) __attribute__((enable_if(a, "")));
void qux(int a) __attribute__((enable_if(false, "")));

template <typename Fn, typename... Args> void call(Fn F, Args... As) {
  F(As...);
}

void test() {
  call(foo); // expected-error{{cannot take address of function 'foo'}}
  call(bar);
  call(baz, 0);
  call(qux, 0); // expected-error{{no matching function for call to 'call'}} expected-note@53{{candidate template ignored: couldn't infer template argument 'Fn'}}

  auto Ptr1 = foo; // expected-error{{cannot take address of function 'foo'}}
  auto Ptr2 = bar;
  auto Ptr3 = baz;
  auto Ptr4 = qux; // expected-error{{variable 'Ptr4' with type 'auto' has incompatible initializer of type '<overloaded function type>'}}
}

template <typename Fn, typename T, typename... Args>
void callMem(Fn F, T t, Args... As) {
  (t.*F)(As...);
}

class Foo {
  void bar() __attribute__((enable_if(true, "")));
  void bar() __attribute__((enable_if(false, "")));

  static void staticBar() __attribute__((enable_if(true, "")));
  static void staticBar() __attribute__((enable_if(false, "")));
};

void testAccess() {
  callMem(&Foo::bar, Foo()); // expected-error{{'bar' is a private member of 'template_deduction::Foo'}} expected-note@-8{{implicitly declared private here}}
  call(&Foo::staticBar); // expected-error{{'staticBar' is a private member of 'template_deduction::Foo'}} expected-note@-6{{implicitly declared private here}}
}
}

namespace template_template_deduction {
void foo() __attribute__((enable_if(false, "")));
template <typename T>
T foo() __attribute__((enable_if(true, "")));

template <typename Fn, typename... Args> auto call(Fn F, Args... As) {
  return F(As...);
}

auto Ok = call(&foo<int>);
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'}}

auto PtrOk = &foo<int>;
auto PtrFail = &foo; // expected-error{{variable 'PtrFail' with type 'auto' has incompatible initializer of type '<overloaded function type>'}}
}
OpenPOWER on IntegriCloud