member-function-pointers.cpp revision 7af4ec744e30d573482aef7a37089d0d32cc07ef
1// RUN: %clang_cc1 %s -emit-llvm -o - -triple=x86_64-apple-darwin9 | FileCheck %s
2
3struct A { int a; void f(); virtual void vf(); };
4struct B { int b; virtual void g(); };
5struct C : B, A { };
6
7void (A::*pa)();
8void (A::*volatile vpa)();
9void (B::*pb)();
10void (C::*pc)();
11
12// CHECK: @pa2 = global %0 { i64 ptrtoint (void ()* @_ZN1A1fEv to i64), i64 0 }, align 8
13void (A::*pa2)() = &A::f;
14
15// CHECK: @pa3 = global %0 { i64 1, i64 0 }, align 8
16void (A::*pa3)() = &A::vf;
17
18// CHECK: @pc2 = global %0 { i64 ptrtoint (void ()* @_ZN1A1fEv to i64), i64 16 }, align 8
19void (C::*pc2)() = &C::f;
20
21// CHECK: @pc3 = global %0 { i64 1, i64 0 }, align 8
22void (A::*pc3)() = &A::vf;
23
24void f() {
25  // CHECK: store i64 0, i64* getelementptr inbounds (%0* @pa, i32 0, i32 0)
26  // CHECK: store i64 0, i64* getelementptr inbounds (%0* @pa, i32 0, i32 1)
27  pa = 0;
28
29  // CHECK: volatile store i64 0, i64* getelementptr inbounds (%0* @vpa, i32 0, i32 0)
30  // CHECK: volatile store i64 0, i64* getelementptr inbounds (%0* @vpa, i32 0, i32 1)
31  vpa = 0;
32
33  // CHECK: store i64 {{.*}}, i64* getelementptr inbounds (%0* @pc, i32 0, i32 0)
34  // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = add i64 {{.*}}, 16
35  // CHECK: store i64 [[ADJ]], i64* getelementptr inbounds (%0* @pc, i32 0, i32 1)
36  pc = pa;
37
38  // CHECK: store i64 {{.*}}, i64* getelementptr inbounds (%0* @pa, i32 0, i32 0)
39  // CHECK: [[ADJ:%[a-zA-Z0-9\.]+]] = sub i64 {{.*}}, 16
40  // CHECK: store i64 [[ADJ]], i64* getelementptr inbounds (%0* @pa, i32 0, i32 1)
41  pa = static_cast<void (A::*)()>(pc);
42}
43
44void f2() {
45  // CHECK: [[pa2ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 0
46  // CHECK: store i64 ptrtoint (void ()* @_ZN1A1fEv to i64), i64* [[pa2ptr]]
47  // CHECK: [[pa2adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa2, i32 0, i32 1
48  // CHECK: store i64 0, i64* [[pa2adj]]
49  void (A::*pa2)() = &A::f;
50
51  // CHECK: [[pa3ptr:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 0
52  // CHECK: store i64 1, i64* [[pa3ptr]]
53  // CHECK: [[pa3adj:%[a-zA-Z0-9\.]+]] = getelementptr inbounds %0* %pa3, i32 0, i32 1
54  // CHECK: store i64 0, i64* [[pa3adj]]
55  void (A::*pa3)() = &A::vf;
56}
57
58void f3(A *a, A &ar) {
59  (a->*pa)();
60  (ar.*pa)();
61}
62
63bool f4() {
64  return pa;
65}
66
67// PR5177
68namespace PR5177 {
69  struct A {
70   bool foo(int*) const;
71  } a;
72
73  struct B1 {
74   bool (A::*pmf)(int*) const;
75   const A* pa;
76
77   B1() : pmf(&A::foo), pa(&a) {}
78   bool operator()() const { return (pa->*pmf)(new int); }
79  };
80
81  void bar(B1 b2) { while (b2()) ; }
82}
83
84// PR5138
85namespace PR5138 {
86  struct foo {
87      virtual void bar(foo *);
88  };
89
90  extern "C" {
91    void baz(foo *);
92  }
93
94  void (foo::*ptr1)(void *) = (void (foo::*)(void *))&foo::bar;
95  void (*ptr2)(void *) = (void (*)(void *))&baz;
96
97  void (foo::*ptr3)(void) = (void (foo::*)(void))&foo::bar;
98}
99
100// PR5593
101namespace PR5593 {
102  struct A { };
103
104  bool f(void (A::*f)()) {
105    return f && f;
106  }
107}
108
109namespace PR5718 {
110  struct A { };
111
112  bool f(void (A::*f)(), void (A::*g)()) {
113    return f == g;
114  }
115}
116
117namespace BoolMemberPointer {
118  struct A { };
119
120  bool f(void (A::*f)()) {
121    return !f;
122  }
123
124  bool g(void (A::*f)()) {
125    if (!!f)
126      return true;
127    return false;
128  }
129}
130
131// PR5940
132namespace PR5940 {
133  class foo {
134  public:
135    virtual void baz(void);
136  };
137
138  void foo::baz(void) {
139       void (foo::*ptr)(void) = &foo::baz;
140  }
141}
142