Skip to content

Commit 3768a55

Browse files
committed
address more comments
1 parent c8843e5 commit 3768a55

File tree

1 file changed

+58
-46
lines changed

1 file changed

+58
-46
lines changed

clang/test/Sema/warn-lifetime-analysis-capture-by.cpp

Lines changed: 58 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,6 @@
22

33
#include "Inputs/lifetime-analysis.h"
44

5-
// ****************************************************************************
6-
// Helper class and functions.
7-
// ****************************************************************************
8-
// Lifetimebound helper functions: Returns a reference to the argument.
9-
std::string_view getLifetimeBoundView(const std::string& s [[clang::lifetimebound]]);
10-
std::string_view getNotLifetimeBoundView(const std::string& s);
11-
const std::string& getLifetimeBoundString(const std::string &s [[clang::lifetimebound]]);
12-
const std::string& getLifetimeBoundString(std::string_view sv [[clang::lifetimebound]]);
13-
145
// ****************************************************************************
156
// Capture an integer
167
// ****************************************************************************
@@ -24,7 +15,7 @@ void use() {
2415
int local;
2516
captureInt(1, // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
2617
x);
27-
captureRValInt(1, x); // expected-warning {{object whose reference is captured by 'x'}}
18+
captureRValInt(1, x); // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
2819
captureInt(local, x);
2920
noCaptureInt(1, x);
3021
noCaptureInt(local, x);
@@ -41,10 +32,10 @@ void captureRValString(std::string &&s [[clang::lifetime_capture_by(x)]], X &x);
4132

4233
void use() {
4334
std::string local_string;
44-
captureString(std::string(), x); // expected-warning {{object whose reference is captured by 'x'}}
35+
captureString(std::string(), x); // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
4536
captureString(local_string, x);
4637
captureRValString(std::move(local_string), x);
47-
captureRValString(std::string(), x); // expected-warning {{object whose reference is captured by 'x'}}
38+
captureRValString(std::string(), x); // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
4839
}
4940
} // namespace capture_string
5041

@@ -57,34 +48,39 @@ void captureStringView(std::string_view s [[clang::lifetime_capture_by(x)]], X &
5748
void captureRValStringView(std::string_view &&sv [[clang::lifetime_capture_by(x)]], X &x);
5849
void noCaptureStringView(std::string_view sv, X &x);
5950

51+
std::string_view getLifetimeBoundView(const std::string& s [[clang::lifetimebound]]);
52+
std::string_view getNotLifetimeBoundView(const std::string& s);
53+
const std::string& getLifetimeBoundString(const std::string &s [[clang::lifetimebound]]);
54+
const std::string& getLifetimeBoundString(std::string_view sv [[clang::lifetimebound]]);
55+
6056
void use() {
6157
std::string_view local_string_view;
6258
std::string local_string;
6359
captureStringView(local_string_view, x);
64-
captureStringView(std::string(), // expected-warning {{object whose reference is captured by 'x'}}
60+
captureStringView(std::string(), // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
6561
x);
6662

6763
captureStringView(getLifetimeBoundView(local_string), x);
6864
captureStringView(getNotLifetimeBoundView(std::string()), x);
6965
captureRValStringView(std::move(local_string_view), x);
70-
captureRValStringView(std::string(), x); // expected-warning {{object whose reference is captured by 'x'}}
66+
captureRValStringView(std::string(), x); // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
7167
captureRValStringView(std::string_view{"abcd"}, x);
7268

7369
noCaptureStringView(local_string_view, x);
7470
noCaptureStringView(std::string(), x);
7571

7672
// With lifetimebound functions.
7773
captureStringView(getLifetimeBoundView(
78-
std::string() // expected-warning {{object whose reference is captured by 'x'}}
74+
std::string() // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
7975
), x);
8076
captureRValStringView(getLifetimeBoundView(local_string), x);
81-
captureRValStringView(getLifetimeBoundView(std::string()), x); // expected-warning {{object whose reference is captured by 'x'}}
77+
captureRValStringView(getLifetimeBoundView(std::string()), x); // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
8278
captureRValStringView(getNotLifetimeBoundView(std::string()), x);
8379
noCaptureStringView(getLifetimeBoundView(std::string()), x);
84-
captureStringView(getLifetimeBoundString(std::string()), x); // expected-warning {{object whose reference is captured by 'x'}}
85-
captureStringView(getLifetimeBoundString(getLifetimeBoundView(std::string())), x); // expected-warning {{object whose reference is captured by 'x'}}
80+
captureStringView(getLifetimeBoundString(std::string()), x); // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
81+
captureStringView(getLifetimeBoundString(getLifetimeBoundView(std::string())), x); // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
8682
captureStringView(getLifetimeBoundString(getLifetimeBoundString(
87-
std::string() // expected-warning {{object whose reference is captured by 'x'}}
83+
std::string() // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
8884
)), x);
8985
}
9086
} // namespace capture_string_view
@@ -99,9 +95,9 @@ namespace capture_pointer {
9995
struct X {} x;
10096
void capturePointer(const std::string* sp [[clang::lifetime_capture_by(x)]], X &x);
10197
void use() {
102-
capturePointer(getLifetimeBoundPointer(std::string()), x); // expected-warning {{object whose reference is captured by 'x'}}
98+
capturePointer(getLifetimeBoundPointer(std::string()), x); // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
10399
capturePointer(getLifetimeBoundPointer(*getLifetimeBoundPointer(
104-
std::string() // expected-warning {{object whose reference is captured by 'x'}}
100+
std::string() // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
105101
)), x);
106102
capturePointer(getNotLifetimeBoundPointer(std::string()), x);
107103

@@ -121,14 +117,14 @@ void captureInitList(std::initializer_list<int> abc [[clang::lifetime_capture_by
121117
std::initializer_list<int> getLifetimeBoundInitList(std::initializer_list<int> abc [[clang::lifetimebound]]);
122118

123119
void use() {
124-
captureVector({1, 2, 3}, x); // expected-warning {{captured by 'x'}}
125-
captureVector(std::vector<int>{}, x); // expected-warning {{captured by 'x'}}
120+
captureVector({1, 2, 3}, x); // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
121+
captureVector(std::vector<int>{}, x); // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
126122
std::vector<int> local_vector;
127123
captureVector(local_vector, x);
128124
int local_array[2];
129125
captureArray(local_array, x);
130-
captureInitList({1, 2}, x); // expected-warning {{captured by 'x'}}
131-
captureInitList(getLifetimeBoundInitList({1, 2}), x); // expected-warning {{captured by 'x'}}
126+
captureInitList({1, 2}, x); // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
127+
captureInitList(getLifetimeBoundInitList({1, 2}), x); // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
132128
}
133129
} // namespace init_lists
134130

@@ -141,7 +137,7 @@ struct S {
141137
void capture(X &x) [[clang::lifetime_capture_by(x)]];
142138
};
143139
void use() {
144-
S{}.capture(x); // expected-warning {{object whose reference is captured by 'x'}}
140+
S{}.capture(x); // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
145141
S s;
146142
s.capture(x);
147143
}
@@ -154,6 +150,8 @@ namespace capture_by_global_unknown {
154150
void captureByGlobal(std::string_view s [[clang::lifetime_capture_by(global)]]);
155151
void captureByUnknown(std::string_view s [[clang::lifetime_capture_by(unknown)]]);
156152

153+
std::string_view getLifetimeBoundView(const std::string& s [[clang::lifetimebound]]);
154+
157155
void use() {
158156
std::string_view local_string_view;
159157
std::string local_string;
@@ -179,12 +177,16 @@ struct S {
179177
void captureInt(const int& x [[clang::lifetime_capture_by(this)]]);
180178
void captureView(std::string_view sv [[clang::lifetime_capture_by(this)]]);
181179
};
180+
std::string_view getLifetimeBoundView(const std::string& s [[clang::lifetimebound]]);
181+
std::string_view getNotLifetimeBoundView(const std::string& s);
182+
const std::string& getLifetimeBoundString(const std::string &s [[clang::lifetimebound]]);
183+
182184
void use() {
183185
S s;
184-
s.captureInt(1); // expected-warning {{object whose reference is captured by 's'}}
185-
s.captureView(std::string()); // expected-warning {{captured by 's'}}
186-
s.captureView(getLifetimeBoundView(std::string())); // expected-warning {{captured by 's'}}
187-
s.captureView(getLifetimeBoundString(std::string())); // expected-warning {{captured by 's'}}
186+
s.captureInt(1); // expected-warning {{object whose reference is captured by 's' will be destroyed at the end of the full-expression}}
187+
s.captureView(std::string()); // expected-warning {{object whose reference is captured by 's' will be destroyed at the end of the full-expression}}
188+
s.captureView(getLifetimeBoundView(std::string())); // expected-warning {{object whose reference is captured by 's' will be destroyed at the end of the full-expression}}
189+
s.captureView(getLifetimeBoundString(std::string())); // expected-warning {{object whose reference is captured by 's' will be destroyed at the end of the full-expression}}
188190
s.captureView(getNotLifetimeBoundView(std::string()));
189191
}
190192
} // namespace capture_by_this
@@ -200,7 +202,7 @@ struct Foo {
200202
void captureField(Foo param [[clang::lifetime_capture_by(x)]], X &x);
201203
void use() {
202204
captureField(Foo{
203-
1 // expected-warning {{captured by 'x'}}
205+
1 // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
204206
}, x);
205207
int local;
206208
captureField(Foo{local}, x);
@@ -213,11 +215,14 @@ void use() {
213215
namespace default_arg {
214216
struct X {} x;
215217
void captureDefaultArg(X &x, std::string_view s [[clang::lifetime_capture_by(x)]] = std::string());
218+
219+
std::string_view getLifetimeBoundView(const std::string& s [[clang::lifetimebound]]);
220+
216221
void useCaptureDefaultArg() {
217222
X x;
218223
captureDefaultArg(x); // FIXME: Diagnose temporary default arg.
219-
captureDefaultArg(x, std::string("temp")); // expected-warning {{captured by 'x'}}
220-
captureDefaultArg(x, getLifetimeBoundView(std::string())); // expected-warning {{captured by 'x'}}
224+
captureDefaultArg(x, std::string("temp")); // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
225+
captureDefaultArg(x, getLifetimeBoundView(std::string())); // expected-warning {{object whose reference is captured by 'x' will be destroyed at the end of the full-expression}}
221226
std::string local;
222227
captureDefaultArg(x, local);
223228
}
@@ -234,9 +239,9 @@ struct MySet {
234239
};
235240
void user_defined_containers() {
236241
MySet<int> set_of_int;
237-
set_of_int.insert(1); // expected-warning {{object whose reference is captured by 'set_of_int' will be destroyed}}
242+
set_of_int.insert(1); // expected-warning {{object whose reference is captured by 'set_of_int' will be destroyed at the end of the full-expression}}
238243
MySet<std::string_view> set_of_sv;
239-
set_of_sv.insert(std::string()); // expected-warning {{object whose reference is captured by 'set_of_sv' will be destroyed}}
244+
set_of_sv.insert(std::string()); // expected-warning {{object whose reference is captured by 'set_of_sv' will be destroyed at the end of the full-expression}}
240245
set_of_sv.insert(std::string_view());
241246
}
242247
} // namespace containers_no_distinction
@@ -257,19 +262,21 @@ template<class T> struct MyVector {
257262
void push_back(const T& t) requires (!IsPointerLikeType<T>);
258263
};
259264

265+
std::string_view getLifetimeBoundView(const std::string& s [[clang::lifetimebound]]);
266+
260267
void use_container() {
261268
std::string local;
262269

263270
MyVector<std::string> vector_of_string;
264271
vector_of_string.push_back(std::string()); // Ok.
265272

266273
MyVector<std::string_view> vector_of_view;
267-
vector_of_view.push_back(std::string()); // expected-warning {{object whose reference is captured by 'vector_of_view'}}
268-
vector_of_view.push_back(getLifetimeBoundView(std::string())); // expected-warning {{captured by 'vector_of_view'}}
274+
vector_of_view.push_back(std::string()); // expected-warning {{object whose reference is captured by 'vector_of_view' will be destroyed at the end of the full-expression}}
275+
vector_of_view.push_back(getLifetimeBoundView(std::string())); // expected-warning {{object whose reference is captured by 'vector_of_view' will be destroyed at the end of the full-expression}}
269276

270277
MyVector<const std::string*> vector_of_pointer;
271-
vector_of_pointer.push_back(getLifetimeBoundPointer(std::string())); // expected-warning {{captured by 'vector_of_pointer'}}
272-
vector_of_pointer.push_back(getLifetimeBoundPointer(*getLifetimeBoundPointer(std::string()))); // expected-warning {{captured by 'vector_of_pointer'}}
278+
vector_of_pointer.push_back(getLifetimeBoundPointer(std::string())); // expected-warning {{object whose reference is captured by 'vector_of_pointer' will be destroyed at the end of the full-expression}}
279+
vector_of_pointer.push_back(getLifetimeBoundPointer(*getLifetimeBoundPointer(std::string()))); // expected-warning {{object whose reference is captured by 'vector_of_pointer' will be destroyed at the end of the full-expression}}
273280
vector_of_pointer.push_back(getLifetimeBoundPointer(local));
274281
vector_of_pointer.push_back(getNotLifetimeBoundPointer(std::string()));
275282
}
@@ -294,15 +301,20 @@ class MyStringViewNotPointer : public std::string_view {};
294301
std::optional<MyStringViewNotPointer> getOptionalMySVNotP();
295302
MyStringViewNotPointer getMySVNotP();
296303

304+
std::string_view getLifetimeBoundView(const std::string& s [[clang::lifetimebound]]);
305+
std::string_view getNotLifetimeBoundView(const std::string& s);
306+
const std::string& getLifetimeBoundString(const std::string &s [[clang::lifetimebound]]);
307+
const std::string& getLifetimeBoundString(std::string_view sv [[clang::lifetimebound]]);
308+
297309
void use_my_view() {
298310
std::string local;
299311
MyVector<MyStringView> vector_of_my_view;
300312
vector_of_my_view.push_back(getMySV());
301313
vector_of_my_view.push_back(MyStringView{});
302314
vector_of_my_view.push_back(std::string_view{});
303-
vector_of_my_view.push_back(std::string{}); // expected-warning {{object whose reference is captured by 'vector_of_my_view'}}
304-
vector_of_my_view.push_back(getLifetimeBoundView(std::string{})); // expected-warning {{captured by 'vector_of_my_view'}}
305-
vector_of_my_view.push_back(getLifetimeBoundString(getLifetimeBoundView(std::string{}))); // expected-warning {{captured by 'vector_of_my_view'}}
315+
vector_of_my_view.push_back(std::string{}); // expected-warning {{object whose reference is captured by 'vector_of_my_view' will be destroyed at the end of the full-expression}}
316+
vector_of_my_view.push_back(getLifetimeBoundView(std::string{})); // expected-warning {{object whose reference is captured by 'vector_of_my_view' will be destroyed at the end of the full-expression}}
317+
vector_of_my_view.push_back(getLifetimeBoundString(getLifetimeBoundView(std::string{}))); // expected-warning {{object whose reference is captured by 'vector_of_my_view' will be destroyed at the end of the full-expression}}
306318
vector_of_my_view.push_back(getNotLifetimeBoundView(getLifetimeBoundString(getLifetimeBoundView(std::string{}))));
307319

308320
// Use with container of other view types.
@@ -319,7 +331,7 @@ void use_with_optional_view() {
319331

320332
std::optional<std::string_view> optional_of_view;
321333
vector_of_view.push_back(optional_of_view.value());
322-
vector_of_view.push_back(getOptionalS().value()); // expected-warning {{captured by 'vector_of_view'}}
334+
vector_of_view.push_back(getOptionalS().value()); // expected-warning {{object whose reference is captured by 'vector_of_view' will be destroyed at the end of the full-expression}}
323335

324336
vector_of_view.push_back(getOptionalSV().value());
325337
vector_of_view.push_back(getOptionalMySV().value());
@@ -340,17 +352,17 @@ void capture3(const std::string_view& s [[clang::lifetime_capture_by(x)]], std::
340352

341353
void use() {
342354
std::vector<std::string_view> x1;
343-
capture1(std::string(), x1); // expected-warning {{captured by 'x1'}}
355+
capture1(std::string(), x1); // expected-warning {{object whose reference is captured by 'x1' will be destroyed at the end of the full-expression}}
344356
capture1(std::string_view(), x1);
345357

346358
std::vector<std::string_view*> x2;
347359
// Clang considers 'const std::string_view&' to refer to the owner
348360
// 'std::string' and not 'std::string_view'. Therefore no diagnostic here.
349361
capture2(std::string_view(), x2);
350-
capture2(std::string(), x2); // expected-warning {{captured by 'x2'}}
362+
capture2(std::string(), x2); // expected-warning {{object whose reference is captured by 'x2' will be destroyed at the end of the full-expression}}
351363

352364
std::vector<std::string_view> x3;
353365
capture3(std::string_view(), x3);
354-
capture3(std::string(), x3); // expected-warning {{captured by 'x3'}}
366+
capture3(std::string(), x3); // expected-warning {{object whose reference is captured by 'x3' will be destroyed at the end of the full-expression}}
355367
}
356368
} // namespace temporary_views

0 commit comments

Comments
 (0)