summaryrefslogtreecommitdiffstats
path: root/build/clang-plugin/tests/TestNoAddRefReleaseOnReturn.cpp
blob: 2e1f83377e50374b46a82d71dd9f16c1f5c4cea7 (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
103
104
105
106
107
108
109
110
#define MOZ_NO_ADDREF_RELEASE_ON_RETURN __attribute__((annotate("moz_no_addref_release_on_return")))

struct Test {
  void AddRef();
  void Release();
  void foo();
};

struct TestD : Test {};

struct S {
  Test* f() MOZ_NO_ADDREF_RELEASE_ON_RETURN;
  Test& g() MOZ_NO_ADDREF_RELEASE_ON_RETURN;
  Test  h() MOZ_NO_ADDREF_RELEASE_ON_RETURN;
};

struct SD {
  TestD* f() MOZ_NO_ADDREF_RELEASE_ON_RETURN;
  TestD& g() MOZ_NO_ADDREF_RELEASE_ON_RETURN;
  TestD  h() MOZ_NO_ADDREF_RELEASE_ON_RETURN;
};

template<class T>
struct X {
  T* f() MOZ_NO_ADDREF_RELEASE_ON_RETURN;
  T& g() MOZ_NO_ADDREF_RELEASE_ON_RETURN;
  T  h() MOZ_NO_ADDREF_RELEASE_ON_RETURN;
};

template<class T>
struct SP {
  T* operator->() MOZ_NO_ADDREF_RELEASE_ON_RETURN;
};

Test* f() MOZ_NO_ADDREF_RELEASE_ON_RETURN;
Test& g() MOZ_NO_ADDREF_RELEASE_ON_RETURN;
Test  h() MOZ_NO_ADDREF_RELEASE_ON_RETURN;

TestD* fd() MOZ_NO_ADDREF_RELEASE_ON_RETURN;
TestD& gd() MOZ_NO_ADDREF_RELEASE_ON_RETURN;
TestD  hd() MOZ_NO_ADDREF_RELEASE_ON_RETURN;

void test() {
  S s;
  s.f()->AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'f'}}
  s.f()->Release(); // expected-error{{'Release' cannot be called on the return value of 'f'}}
  s.f()->foo();
  s.g().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'g'}}
  s.g().Release(); // expected-error{{'Release' cannot be called on the return value of 'g'}}
  s.g().foo();
  s.h().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'h'}}
  s.h().Release(); // expected-error{{'Release' cannot be called on the return value of 'h'}}
  s.h().foo();
  SD sd;
  sd.f()->AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'f'}}
  sd.f()->Release(); // expected-error{{'Release' cannot be called on the return value of 'f'}}
  sd.f()->foo();
  sd.g().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'g'}}
  sd.g().Release(); // expected-error{{'Release' cannot be called on the return value of 'g'}}
  sd.g().foo();
  sd.h().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'h'}}
  sd.h().Release(); // expected-error{{'Release' cannot be called on the return value of 'h'}}
  sd.h().foo();
  X<Test> x;
  x.f()->AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'f'}}
  x.f()->Release(); // expected-error{{'Release' cannot be called on the return value of 'f'}}
  x.f()->foo();
  x.g().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'g'}}
  x.g().Release(); // expected-error{{'Release' cannot be called on the return value of 'g'}}
  x.g().foo();
  x.h().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'h'}}
  x.h().Release(); // expected-error{{'Release' cannot be called on the return value of 'h'}}
  x.h().foo();
  X<TestD> xd;
  xd.f()->AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'f'}}
  xd.f()->Release(); // expected-error{{'Release' cannot be called on the return value of 'f'}}
  xd.f()->foo();
  xd.g().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'g'}}
  xd.g().Release(); // expected-error{{'Release' cannot be called on the return value of 'g'}}
  xd.g().foo();
  xd.h().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'h'}}
  xd.h().Release(); // expected-error{{'Release' cannot be called on the return value of 'h'}}
  xd.h().foo();
  SP<Test> sp;
  sp->AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'operator->'}}
  sp->Release(); // expected-error{{'Release' cannot be called on the return value of 'operator->'}}
  sp->foo();
  SP<TestD> spd;
  spd->AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'operator->'}}
  spd->Release(); // expected-error{{'Release' cannot be called on the return value of 'operator->'}}
  spd->foo();
  f()->AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'f'}}
  f()->Release(); // expected-error{{'Release' cannot be called on the return value of 'f'}}
  f()->foo();
  g().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'g'}}
  g().Release(); // expected-error{{'Release' cannot be called on the return value of 'g'}}
  g().foo();
  h().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'h'}}
  h().Release(); // expected-error{{'Release' cannot be called on the return value of 'h'}}
  h().foo();
  fd()->AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'fd'}}
  fd()->Release(); // expected-error{{'Release' cannot be called on the return value of 'fd'}}
  fd()->foo();
  gd().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'gd'}}
  gd().Release(); // expected-error{{'Release' cannot be called on the return value of 'gd'}}
  gd().foo();
  hd().AddRef(); // expected-error{{'AddRef' cannot be called on the return value of 'hd'}}
  hd().Release(); // expected-error{{'Release' cannot be called on the return value of 'hd'}}
  hd().foo();
}