1 // RUN: %clang_cc1 -std=c++2a -verify %s
3 namespace usage_invalid
{
4 // FIXME: Should we diagnose a void return type?
5 void voidreturn(int ¶m
[[clang::lifetimebound
]]);
7 int *not_class_member() [[clang::lifetimebound
]]; // expected-error {{non-member function has no implicit object parameter}}
9 A() [[clang::lifetimebound
]]; // expected-error {{cannot be applied to a constructor}}
10 ~A() [[clang::lifetimebound
]]; // expected-error {{cannot be applied to a destructor}}
11 static int *static_class_member() [[clang::lifetimebound
]]; // expected-error {{static member function has no implicit object parameter}}
12 int not_function
[[clang::lifetimebound
]]; // expected-error {{only applies to parameters and implicit object parameters}}
13 int [[clang::lifetimebound
]] also_not_function
; // expected-error {{cannot be applied to types}}
15 int *attr_with_param(int ¶m
[[clang::lifetimebound(42)]]); // expected-error {{takes no arguments}}
19 struct IntRef
{ int *target
; };
21 int &refparam(int ¶m
[[clang::lifetimebound
]]);
22 int &classparam(IntRef param
[[clang::lifetimebound
]]);
24 // Do not diagnose non-void return types; they can still be lifetime-bound.
25 long long ptrintcast(int ¶m
[[clang::lifetimebound
]]) {
26 return (long long)¶m
;
29 int &intptrcast(long long param
[[clang::lifetimebound
]]) {
36 int *class_member() [[clang::lifetimebound
]];
37 operator int*() [[clang::lifetimebound
]];
40 int *p
= A().class_member(); // expected-warning {{temporary whose address is used as value of local variable 'p' will be destroyed at the end of the full-expression}}
41 int *q
= A(); // expected-warning {{temporary whose address is used as value of local variable 'q' will be destroyed at the end of the full-expression}}
42 int *r
= A(1); // expected-warning {{temporary whose address is used as value of local variable 'r' will be destroyed at the end of the full-expression}}
47 using size_t = __SIZE_TYPE__
;
52 char &operator[](size_t) const [[clang::lifetimebound
]];
54 string
operator""s(const char *, size_t);
58 string_view(const char *p
[[clang::lifetimebound
]]);
59 string_view(const string
&s
[[clang::lifetimebound
]]);
61 string_view
operator""sv(const char *, size_t);
68 template<typename K
, typename V
> struct map
{};
70 # 68 "attr-lifetimebound.cpp" 2
72 using std::operator""s
;
73 using std::operator""sv
;
75 namespace p0936r0_examples
{
76 std::string_view s
= "foo"s
; // expected-warning {{temporary}}
78 std::string
operator+(std::string_view s1
, std::string_view s2
);
80 std::string_view sv
= "hi";
81 std::string_view sv2
= sv
+ sv
; // expected-warning {{temporary}}
82 sv2
= sv
+ sv
; // FIXME: can we infer that we should warn here too?
85 struct X
{ int a
, b
; };
86 const int &f(const X
&x
[[clang::lifetimebound
]]) { return x
.a
; }
87 const int &r
= f(X()); // expected-warning {{temporary}}
89 char &c
= std::string("hello my pretty long strong")[0]; // expected-warning {{temporary}}
91 struct reversed_range
{
97 template <typename R
> reversed_range
reversed(R
&&r
[[clang::lifetimebound
]]) {
98 return reversed_range
{r
.data(), r
.size()};
101 std::vector
make_vector();
102 void use_reversed_range() {
103 // FIXME: Don't expose the name of the internal range variable.
104 for (auto x
: reversed(make_vector())) {} // expected-warning {{temporary implicitly bound to local reference will be destroyed at the end of the full-expression}}
107 template <typename K
, typename V
>
108 const V
&findOrDefault(const std::map
<K
, V
> &m
[[clang::lifetimebound
]],
110 const V
&defvalue
[[clang::lifetimebound
]]);
112 // FIXME: Maybe weaken the wording here: "local reference 'v' could bind to temporary that will be destroyed at end of full-expression"?
113 std::map
<std::string
, std::string
> m
;
114 const std::string
&v
= findOrDefault(m
, "foo"s
, "bar"s
); // expected-warning {{temporary bound to local reference 'v'}}