aboutsummaryrefslogtreecommitdiff
path: root/test/SemaCXX/warn-thread-safety.cpp
blob: 39a3fa2e4de1c473cb76171349f7a5a7e24a5033 (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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
// RUN: %clang_cc1 -fsyntax-only -verify %s

/***********************************
 *  No Thread Safety Analysis (noanal)
 ***********************************/

// FIXME: Right now we cannot parse attributes put on function definitions
// We would like to patch this at some point.

#if !__has_attribute(no_thread_safety_analysis)
#error "Should support no_thread_safety_analysis attribute"
#endif

void noanal_function() __attribute__((no_thread_safety_analysis));

void noanal_function() __attribute__((no_thread_safety_analysis(1))); // \
  expected-error {{attribute takes no arguments}}

int noanal_testfn(int y) __attribute__((no_thread_safety_analysis));

int noanal_testfn(int y) {
  int x __attribute__((no_thread_safety_analysis)) = y; // \
    expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
  return x;
};

int noanal_test_var __attribute__((no_thread_safety_analysis)); // \
  expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}

class NoanalFoo {
 private:
  int test_field __attribute__((no_thread_safety_analysis)); // \
    expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
  void test_method() __attribute__((no_thread_safety_analysis));
};

class __attribute__((no_thread_safety_analysis)) NoanalTestClass { // \
    expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}
};

void noanal_fun_params(int lvar __attribute__((no_thread_safety_analysis))); // \
  expected-warning {{'no_thread_safety_analysis' attribute only applies to functions and methods}}


/***********************************
 *  Guarded Var Attribute (gv)
 ***********************************/

#if !__has_attribute(guarded_var)
#error "Should support guarded_var attribute"
#endif

int gv_var_noargs __attribute__((guarded_var));

int gv_var_args __attribute__((guarded_var(1))); // \
    expected-error {{attribute takes no arguments}}

class GVFoo {
 private:
  int gv_field_noargs __attribute__((guarded_var));
  int gv_field_args __attribute__((guarded_var(1))); // \
      expected-error {{attribute takes no arguments}}
};

class __attribute__((guarded_var)) GV { // \
      expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
};

void gv_function() __attribute__((guarded_var)); // \
    expected-warning {{'guarded_var' attribute only applies to fields and global variables}}

void gv_function_params(int gv_lvar __attribute__((guarded_var))); // \
    expected-warning {{'guarded_var' attribute only applies to fields and global variables}}

int gv_testfn(int y){
  int x __attribute__((guarded_var)) = y; // \
      expected-warning {{'guarded_var' attribute only applies to fields and global variables}}
  return x;
}

/***********************************
 *  Pt Guarded Var Attribute (pgv)
 ***********************************/

//FIXME: add support for boost::scoped_ptr<int> fancyptr  and references

#if !__has_attribute(pt_guarded_var)
#error "Should support pt_guarded_var attribute"
#endif

int *pgv_pt_var_noargs __attribute__((pt_guarded_var));

int pgv_var_noargs __attribute__((pt_guarded_var)); // \
    expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}

class PGVFoo {
 private:
  int *pt_field_noargs __attribute__((pt_guarded_var));
  int field_noargs __attribute__((pt_guarded_var)); // \
    expected-warning {{'pt_guarded_var' only applies to pointer types; type here is 'int'}}
  int *gv_field_args __attribute__((pt_guarded_var(1))); // \
    expected-error {{attribute takes no arguments}}
};

class __attribute__((pt_guarded_var)) PGV { // \
    expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
};

int *pgv_var_args __attribute__((pt_guarded_var(1))); // \
  expected-error {{attribute takes no arguments}}


void pgv_function() __attribute__((pt_guarded_var)); // \
  expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}

void pgv_function_params(int *gv_lvar __attribute__((pt_guarded_var))); // \
  expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}

void pgv_testfn(int y){
  int *x __attribute__((pt_guarded_var)) = new int(0); // \
    expected-warning {{'pt_guarded_var' attribute only applies to fields and global variables}}
  delete x;
}

/***********************************
 *  Lockable Attribute (l)
 ***********************************/

//FIXME: In future we may want to add support for structs, ObjC classes, etc.

#if !__has_attribute(lockable)
#error "Should support lockable attribute"
#endif

class __attribute__((lockable)) LTestClass {
};

class __attribute__((lockable (1))) LTestClass_args { // \
    expected-error {{attribute takes no arguments}}
};

void l_test_function() __attribute__((lockable));  // \
  expected-warning {{'lockable' attribute only applies to classes}}

int l_testfn(int y) {
  int x __attribute__((lockable)) = y; // \
    expected-warning {{'lockable' attribute only applies to classes}}
  return x;
}

int l_test_var __attribute__((lockable)); // \
  expected-warning {{'lockable' attribute only applies to classes}}

class LFoo {
 private:
  int test_field __attribute__((lockable)); // \
    expected-warning {{'lockable' attribute only applies to classes}}
  void test_method() __attribute__((lockable)); // \
    expected-warning {{'lockable' attribute only applies to classes}}
};


void l_function_params(int lvar __attribute__((lockable))); // \
  expected-warning {{'lockable' attribute only applies to classes}}


/***********************************
 *  Scoped Lockable Attribute (sl)
 ***********************************/

#if !__has_attribute(scoped_lockable)
#error "Should support scoped_lockable attribute"
#endif

class __attribute__((scoped_lockable)) SLTestClass {
};

class __attribute__((scoped_lockable (1))) SLTestClass_args { // \
    expected-error {{attribute takes no arguments}}
};

void sl_test_function() __attribute__((scoped_lockable));  // \
  expected-warning {{'scoped_lockable' attribute only applies to classes}}

int sl_testfn(int y) {
  int x __attribute__((scoped_lockable)) = y; // \
    expected-warning {{'scoped_lockable' attribute only applies to classes}}
  return x;
}

int sl_test_var __attribute__((scoped_lockable)); // \
  expected-warning {{'scoped_lockable' attribute only applies to classes}}

class SLFoo {
 private:
  int test_field __attribute__((scoped_lockable)); // \
    expected-warning {{'scoped_lockable' attribute only applies to classes}}
  void test_method() __attribute__((scoped_lockable)); // \
    expected-warning {{'scoped_lockable' attribute only applies to classes}}
};


void sl_function_params(int lvar __attribute__((scoped_lockable))); // \
  expected-warning {{'scoped_lockable' attribute only applies to classes}}