blob: 0848cf98c160b6c44d90777aeeac9432f5a604eb [file] [edit]
// RUN: %clang_cc1 -std=c++23 -verify %s
struct S {
const int *x;
void captureInt(const int&x [[clang::lifetime_capture_by_this]]) { this->x = &x; }
};
///////////////////////////
// Test for valid usages.
///////////////////////////
[[clang::lifetime_capture_by(unknown)]] // expected-error {{'clang::lifetime_capture_by' attribute only applies to parameters and implicit object parameters}}
void nonMember(
const int &x1 [[clang::lifetime_capture_by(s, t)]],
S &s,
S &t,
const int &x2 [[clang::lifetime_capture_by(12345 + 12)]], // expected-error {{'lifetime_capture_by' attribute argument '12345 + 12' is not a known function parameter; must be a function parameter, 'this', 'global' or 'unknown'}}
const int &x3 [[clang::lifetime_capture_by(abcdefgh)]], // expected-error {{'lifetime_capture_by' attribute argument 'abcdefgh' is not a known function parameter; must be a function parameter, 'this', 'global' or 'unknown'}}
const int &x4 [[clang::lifetime_capture_by("abcdefgh")]], // expected-error {{'lifetime_capture_by' attribute argument '"abcdefgh"' is not a known function parameter; must be a function parameter, 'this', 'global' or 'unknown'}}
const int &x5 [[clang::lifetime_capture_by_this]], // expected-error {{'lifetime_capture_by_this' attribute requires an implicit object parameter}}
const int &x6 [[clang::lifetime_capture_by()]], // expected-error {{'lifetime_capture_by' attribute specifies no capturing entity}}
const int& x7 [[clang::lifetime_capture_by(u,
x7)]], // expected-error {{'lifetime_capture_by' argument references itself}}
const int &x8 [[clang::lifetime_capture_by(global)]], // expected-warning {{'lifetime_capture_by(global)' is deprecated; use 'lifetime_capture_by_global' instead}}
const int &x9 [[clang::lifetime_capture_by(unknown)]], // expected-warning {{'lifetime_capture_by(unknown)' is deprecated; use 'lifetime_capture_by_unknown' instead}}
const int &x10 [[clang::lifetime_capture_by_global(s)]], // expected-error {{'clang::lifetime_capture_by_global' attribute takes no arguments}}
const int &x11 [[clang::lifetime_capture_by(this)]], // expected-error {{'lifetime_capture_by' argument references unavailable implicit 'this'}} // expected-warning {{'lifetime_capture_by(this)' is deprecated; use 'lifetime_capture_by_this' instead}}
const int &test_memory_leak[[clang::lifetime_capture_by(x1,x2, x3, x4, x5, x6, x7, x8, x9)]],
const S& u
)
{
s.captureInt(x1);
}
void unknown_param_name(const int& unknown, // expected-error {{parameter cannot be named 'unknown' while using 'lifetime_capture_by(unknown)'}}
const int& s [[clang::lifetime_capture_by(unknown)]]); // expected-warning {{'lifetime_capture_by(unknown)' is deprecated; use 'lifetime_capture_by_unknown' instead}}
void global_param_name(const int& global, // expected-error {{parameter cannot be named 'global' while using 'lifetime_capture_by(global)'}}
const int& s [[clang::lifetime_capture_by(global)]]); // expected-warning {{'lifetime_capture_by(global)' is deprecated; use 'lifetime_capture_by_global' instead}}
void no_such_param(int i [[clang::lifetime_capture_by(no_such_param)]]); // expected-error {{'lifetime_capture_by' attribute argument 'no_such_param' is not a known function parameter; must be a function parameter, 'this', 'global' or 'unknown'}}
void use_no_such_param() { no_such_param(0); }
struct T {
void member(
const int &x [[clang::lifetime_capture_by(s)]],
S &s,
S &t,
const int &y [[clang::lifetime_capture_by(s)]],
const int &z [[clang::lifetime_capture_by(x, y), clang::lifetime_capture_by_this]],
const int &u [[clang::lifetime_capture_by(global, unknown, x, s)]]) // expected-warning 2 {{deprecated}}
{
s.captureInt(x);
}
void explicit_this1(this T& self, const int &x [[clang::lifetime_capture_by(self)]]);
void explicit_this2(this T& self, const int &x [[clang::lifetime_capture_by(this)]]); // expected-warning {{'lifetime_capture_by(this)' is deprecated; use 'lifetime_capture_by_this' instead}} expected-error {{argument references unavailable implicit 'this'}}
};
void duplicate_parameter_list(
const int &x [[clang::lifetime_capture_by(s),
clang::lifetime_capture_by(t)]], // expected-error {{multiple 'lifetime_capture_by' attributes specified}}
S &s, S &t);
void duplicate_global(
const int &x [[clang::lifetime_capture_by_global,
clang::lifetime_capture_by_global]]); // expected-error {{multiple 'lifetime_capture_by_global' attributes specified}}
void duplicate_unknown(
const int &x [[clang::lifetime_capture_by_unknown,
clang::lifetime_capture_by_unknown]]); // expected-error {{multiple 'lifetime_capture_by_unknown' attributes specified}}
struct U {
void duplicate_this(
const int &x [[clang::lifetime_capture_by_this,
clang::lifetime_capture_by_this]]); // expected-error {{multiple 'lifetime_capture_by_this' attributes specified}}
void different_spellings(
const int &x [[clang::lifetime_capture_by(s),
clang::lifetime_capture_by_this,
clang::lifetime_capture_by_global,
clang::lifetime_capture_by_unknown]],
S &s);
void deprecated_this_spelling_is_distinct(
const int &x [[clang::lifetime_capture_by(this), // expected-warning {{'lifetime_capture_by(this)' is deprecated; use 'lifetime_capture_by_this' instead}}
clang::lifetime_capture_by_this]]);
};