aboutsummaryrefslogtreecommitdiff
path: root/test/CodeGenCXX/constructor-destructor-return-this.cpp
blob: 1ff922de60f3958fc411753533d9f68a69632ad9 (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
//RUN: %clang_cc1 %s -emit-llvm -o - -triple=thumbv7-apple-ios3.0 -target-abi apcs-gnu | FileCheck %s

// For constructors/desctructors that return 'this', if there exists a callsite
// that returns 'this' and is immediately before the return instruction, make
// sure we are using the return value from the callsite.
// rdar://12818789

// CHECK: define linkonce_odr [[A:%.*]] @_ZN11ObjectCacheC1Ev([[A]] %this) unnamed_addr
// CHECK: [[THIS1:%.*]] = call [[A]] @_ZN11ObjectCacheC2Ev(
// CHECK-NEXT: ret [[A]] [[THIS1]]

// CHECK: define linkonce_odr [[A:%.*]] @_ZN5TimerI11ObjectCacheEC1EPS0_MS0_FvPS1_E([[A]] %this
// CHECK: [[THIS1:%.*]] = call [[A]] @_ZN5TimerI11ObjectCacheEC2EPS0_MS0_FvPS1_E(
// CHECK-NEXT: ret [[A]] [[THIS1]]

// CHECK: define linkonce_odr [[A:%.*]] @_ZN5TimerI11ObjectCacheED1Ev([[A]] %this) unnamed_addr
// CHECK: [[THIS1:%.*]] = call [[A]] @_ZN5TimerI11ObjectCacheED2Ev(
// CHECK-NEXT: ret [[A]] [[THIS1]]

// CHECK: define linkonce_odr [[A:%.*]] @_ZN5TimerI11ObjectCacheED2Ev([[A]] %this) unnamed_addr
// CHECK: [[THIS1:%.*]] = call [[B:%.*]] @_ZN9TimerBaseD2Ev(
// CHECK-NEXT: [[THIS2:%.*]] = bitcast [[B]] [[THIS1]] to [[A]]
// CHECK-NEXT: ret [[A]] [[THIS2]]

class TimerBase {
public:
    TimerBase();
    virtual ~TimerBase();
};

template <typename TimerFiredClass> class Timer : public TimerBase {
public:
    typedef void (TimerFiredClass::*TimerFiredFunction)(Timer*);

    Timer(TimerFiredClass* o, TimerFiredFunction f)
        : m_object(o), m_function(f) { }

private:
    virtual void fired() { (m_object->*m_function)(this); }

    TimerFiredClass* m_object;
    TimerFiredFunction m_function;
};

class ObjectCache {
public:
    explicit ObjectCache();
    ~ObjectCache();

private:
    Timer<ObjectCache> m_notificationPostTimer;
};

inline ObjectCache::ObjectCache() : m_notificationPostTimer(this, 0) { }
inline ObjectCache::~ObjectCache() { }

ObjectCache *test() {
  ObjectCache *dd = new ObjectCache();
  return dd;
}