Skip to content

Commit ea301d7

Browse files
committed
update tests
1 parent cfe3362 commit ea301d7

File tree

2 files changed

+40
-27
lines changed

2 files changed

+40
-27
lines changed

clang/lib/Sema/CheckExprLifetime.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1438,7 +1438,6 @@ checkExprLifetimeImpl(Sema &SemaRef, const InitializedEntity *InitEntity,
14381438
return false;
14391439
};
14401440

1441-
bool HasReferenceBinding = Init->isGLValue();
14421441
llvm::SmallVector<IndirectLocalPathEntry, 8> Path;
14431442
switch (LK) {
14441443
case LK_Assignment: {
@@ -1460,7 +1459,7 @@ checkExprLifetimeImpl(Sema &SemaRef, const InitializedEntity *InitEntity,
14601459
break;
14611460
}
14621461

1463-
if (HasReferenceBinding)
1462+
if (Init->isGLValue())
14641463
visitLocalsRetainedByReferenceBinding(Path, Init, RK_ReferenceBinding,
14651464
TemporaryVisitor);
14661465
else

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

Lines changed: 39 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,21 @@
1-
// RUN: %clang_cc1 --std=c++20 -fsyntax-only -Wdangling -Wdangling-field -Wreturn-stack-address -verify %s
1+
// RUN: %clang_cc1 --std=c++20 -fsyntax-only -verify %s
22

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

5-
struct X {} x;
6-
X x;
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]]);
713

814
// ****************************************************************************
915
// Capture an integer
1016
// ****************************************************************************
1117
namespace capture_int {
18+
struct X {} x;
1219
void captureInt(const int &i [[clang::lifetime_capture_by(x)]], X &x);
1320
void captureRValInt(int &&i [[clang::lifetime_capture_by(x)]], X &x);
1421
void noCaptureInt(int i [[clang::lifetime_capture_by(x)]], X &x);
@@ -27,12 +34,8 @@ void use() {
2734
// ****************************************************************************
2835
// Capture std::string (gsl owner types)
2936
// ****************************************************************************
30-
std::string_view getLifetimeBoundView(const std::string& s [[clang::lifetimebound]]);
31-
std::string_view getNotLifetimeBoundView(const std::string& s);
32-
const std::string& getLifetimeBoundString(const std::string &s [[clang::lifetimebound]]);
33-
const std::string& getLifetimeBoundString(std::string_view sv [[clang::lifetimebound]]);
34-
3537
namespace capture_string {
38+
struct X {} x;
3639
void captureString(const std::string &s [[clang::lifetime_capture_by(x)]], X &x);
3740
void captureRValString(std::string &&s [[clang::lifetime_capture_by(x)]], X &x);
3841

@@ -49,6 +52,7 @@ void use() {
4952
// Capture std::string_view (gsl pointer types)
5053
// ****************************************************************************
5154
namespace capture_string_view {
55+
struct X {} x;
5256
void captureStringView(std::string_view s [[clang::lifetime_capture_by(x)]], X &x);
5357
void captureRValStringView(std::string_view &&sv [[clang::lifetime_capture_by(x)]], X &x);
5458
void noCaptureStringView(std::string_view sv, X &x);
@@ -92,6 +96,7 @@ const std::string* getLifetimeBoundPointer(const std::string &s [[clang::lifetim
9296
const std::string* getNotLifetimeBoundPointer(const std::string &s);
9397

9498
namespace capture_pointer {
99+
struct X {} x;
95100
void capturePointer(const std::string* sp [[clang::lifetime_capture_by(x)]], X &x);
96101
void use() {
97102
capturePointer(getLifetimeBoundPointer(std::string()), x); // expected-warning {{object whose reference is captured by 'x'}}
@@ -107,25 +112,31 @@ void use() {
107112
// Arrays and initializer lists.
108113
// ****************************************************************************
109114
namespace init_lists {
115+
struct X {} x;
110116
void captureVector(const std::vector<int> &a [[clang::lifetime_capture_by(x)]], X &x);
111117
void captureArray(int array [[clang::lifetime_capture_by(x)]] [2], X &x);
112118
void captureInitList(std::initializer_list<int> abc [[clang::lifetime_capture_by(x)]], X &x);
113119

120+
121+
std::initializer_list<int> getLifetimeBoundInitList(std::initializer_list<int> abc [[clang::lifetimebound]]);
122+
114123
void use() {
115-
captureVector({1, 2, 3}, x); // expected-warning {{capture}}
116-
captureVector(std::vector<int>{}, x); // expected-warning {{capture}}
124+
captureVector({1, 2, 3}, x); // expected-warning {{captured by 'x'}}
125+
captureVector(std::vector<int>{}, x); // expected-warning {{captured by 'x'}}
117126
std::vector<int> local_vector;
118127
captureVector(local_vector, x);
119128
int local_array[2];
120129
captureArray(local_array, x);
121-
captureInitList({1, 2}, x); // expected-warning {{capture}}
122-
}
130+
captureInitList({1, 2}, x); // expected-warning {{captured by 'x'}}
131+
captureInitList(getLifetimeBoundInitList({1, 2}), x); // expected-warning {{captured by 'x'}}
123132
}
133+
} // namespace init_lists
124134

125135
// ****************************************************************************
126136
// Implicit object param 'this' is captured
127137
// ****************************************************************************
128138
namespace this_is_captured {
139+
struct X {} x;
129140
struct S {
130141
void capture(X &x) [[clang::lifetime_capture_by(x)]];
131142
};
@@ -148,13 +159,13 @@ void use() {
148159
std::string local_string;
149160
// capture by global.
150161
captureByGlobal(std::string()); // expected-warning {{object whose reference is captured will be destroyed at the end of the full-expression}}
151-
captureByGlobal(getLifetimeBoundView(std::string())); // expected-warning {{captured}}
162+
captureByGlobal(getLifetimeBoundView(std::string())); // expected-warning {{object whose reference is captured will be destroyed at the end of the full-expression}}
152163
captureByGlobal(local_string);
153164
captureByGlobal(local_string_view);
154165

155166
// capture by unknown.
156167
captureByUnknown(std::string()); // expected-warning {{object whose reference is captured will be destroyed at the end of the full-expression}}
157-
captureByUnknown(getLifetimeBoundView(std::string())); // expected-warning {{captured}}
168+
captureByUnknown(getLifetimeBoundView(std::string())); // expected-warning {{object whose reference is captured will be destroyed at the end of the full-expression}}
158169
captureByUnknown(local_string);
159170
captureByUnknown(local_string_view);
160171
}
@@ -171,9 +182,9 @@ struct S {
171182
void use() {
172183
S s;
173184
s.captureInt(1); // expected-warning {{object whose reference is captured by 's'}}
174-
s.captureView(std::string()); // expected-warning {{captured}}
175-
s.captureView(getLifetimeBoundView(std::string())); // expected-warning {{captured}}
176-
s.captureView(getLifetimeBoundString(std::string())); // expected-warning {{captured}}
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'}}
177188
s.captureView(getNotLifetimeBoundView(std::string()));
178189
}
179190
} // namespace capture_by_this
@@ -182,13 +193,14 @@ void use() {
182193
// Struct with field as a reference
183194
// ****************************************************************************
184195
namespace reference_field {
196+
struct X {} x;
185197
struct Foo {
186198
const int& b;
187199
};
188200
void captureField(Foo param [[clang::lifetime_capture_by(x)]], X &x);
189201
void use() {
190202
captureField(Foo{
191-
1 // expected-warning {{capture}}
203+
1 // expected-warning {{captured by 'x'}}
192204
}, x);
193205
int local;
194206
captureField(Foo{local}, x);
@@ -199,11 +211,13 @@ void use() {
199211
// Capture default argument.
200212
// ****************************************************************************
201213
namespace default_arg {
214+
struct X {} x;
202215
void captureDefaultArg(X &x, std::string_view s [[clang::lifetime_capture_by(x)]] = std::string());
203216
void useCaptureDefaultArg() {
204217
X x;
205218
captureDefaultArg(x); // FIXME: Diagnose temporary default arg.
206-
captureDefaultArg(x, std::string("temp")); // expected-warning {{captured}}
219+
captureDefaultArg(x, std::string("temp")); // expected-warning {{captured by 'x'}}
220+
captureDefaultArg(x, getLifetimeBoundView(std::string())); // expected-warning {{captured by 'x'}}
207221
std::string local;
208222
captureDefaultArg(x, local);
209223
}
@@ -251,11 +265,11 @@ void use_container() {
251265

252266
MyVector<std::string_view> vector_of_view;
253267
vector_of_view.push_back(std::string()); // expected-warning {{object whose reference is captured by 'vector_of_view'}}
254-
vector_of_view.push_back(getLifetimeBoundView(std::string())); // expected-warning {{captured}}
268+
vector_of_view.push_back(getLifetimeBoundView(std::string())); // expected-warning {{captured by 'vector_of_view'}}
255269

256270
MyVector<const std::string*> vector_of_pointer;
257-
vector_of_pointer.push_back(getLifetimeBoundPointer(std::string())); // expected-warning {{captured}}
258-
vector_of_pointer.push_back(getLifetimeBoundPointer(*getLifetimeBoundPointer(std::string()))); // expected-warning {{captured}}
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'}}
259273
vector_of_pointer.push_back(getLifetimeBoundPointer(local));
260274
vector_of_pointer.push_back(getNotLifetimeBoundPointer(std::string()));
261275
}
@@ -287,8 +301,8 @@ void use_my_view() {
287301
vector_of_my_view.push_back(MyStringView{});
288302
vector_of_my_view.push_back(std::string_view{});
289303
vector_of_my_view.push_back(std::string{}); // expected-warning {{object whose reference is captured by 'vector_of_my_view'}}
290-
vector_of_my_view.push_back(getLifetimeBoundView(std::string{})); // expected-warning {{captured}}
291-
vector_of_my_view.push_back(getLifetimeBoundString(getLifetimeBoundView(std::string{}))); // expected-warning {{captured}}
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'}}
292306
vector_of_my_view.push_back(getNotLifetimeBoundView(getLifetimeBoundString(getLifetimeBoundView(std::string{}))));
293307

294308
// Use with container of other view types.
@@ -305,7 +319,7 @@ void use_with_optional_view() {
305319

306320
std::optional<std::string_view> optional_of_view;
307321
vector_of_view.push_back(optional_of_view.value());
308-
vector_of_view.push_back(getOptionalS().value()); // expected-warning {{captured}}
322+
vector_of_view.push_back(getOptionalS().value()); // expected-warning {{captured by 'vector_of_view'}}
309323

310324
vector_of_view.push_back(getOptionalSV().value());
311325
vector_of_view.push_back(getOptionalMySV().value());

0 commit comments

Comments
 (0)