Skip to content

Commit 85d3f92

Browse files
committed
[clang] Informative error for lifetimebound in decl-spec
Emit a bit more informative error when the `[[clang::lifetimebound]]` attribute is wrongly appearing on a decl-spec: "'lifetimebound' attribute only applies to parameters and implicit object parameters", instead of: "'lifetimebound' attribute cannot be applied to types". The new error is also consistent with the diagnostic emitted when the attribute is misplaced in other parts of a declarator.
1 parent 9b49da2 commit 85d3f92

File tree

2 files changed

+10
-4
lines changed

2 files changed

+10
-4
lines changed

clang/lib/Parse/ParseDecl.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3703,8 +3703,14 @@ void Parser::ParseDeclarationSpecifiers(
37033703
// We reject AT_LifetimeBound and AT_AnyX86NoCfCheck, even though they
37043704
// are type attributes, because we historically haven't allowed these
37053705
// to be used as type attributes in C++11 / C23 syntax.
3706-
if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
3707-
PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
3706+
if (PA.getKind() == ParsedAttr::AT_LifetimeBound) {
3707+
Diag(PA.getLoc(), diag::err_attribute_wrong_decl_type_str)
3708+
<< PA << PA.isRegularKeywordAttribute()
3709+
<< "parameters and implicit object parameters";
3710+
PA.setInvalid();
3711+
continue;
3712+
}
3713+
if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
37083714
continue;
37093715
Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
37103716
<< PA << PA.isRegularKeywordAttribute();

clang/test/SemaCXX/attr-lifetimebound.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ namespace usage_invalid {
1010
static int *static_class_member() [[clang::lifetimebound]]; // expected-error {{static member function has no implicit object parameter}}
1111
int *explicit_object(this A&) [[clang::lifetimebound]]; // expected-error {{explicit object member function has no implicit object parameter}}
1212
int attr_on_var [[clang::lifetimebound]]; // expected-error {{only applies to parameters and implicit object parameters}}
13-
int [[clang::lifetimebound]] attr_on_int; // expected-error {{cannot be applied to types}}
13+
int [[clang::lifetimebound]] attr_on_int; // expected-error {{'lifetimebound' attribute only applies to parameters and implicit object parameters}}
1414
int * [[clang::lifetimebound]] attr_on_int_ptr; // expected-error {{'lifetimebound' attribute only applies to parameters and implicit object parameters}}
1515
int * [[clang::lifetimebound]] * attr_on_int_ptr_ptr; // expected-error {{'lifetimebound' attribute only applies to parameters and implicit object parameters}}
1616
int (* [[clang::lifetimebound]] attr_on_func_ptr)(); // expected-error {{'lifetimebound' attribute only applies to parameters and implicit object parameters}}
@@ -19,7 +19,7 @@ namespace usage_invalid {
1919
int *attr_with_param(int &param [[clang::lifetimebound(42)]]); // expected-error {{takes no arguments}}
2020

2121
void attr_on_ptr_arg(int * [[clang::lifetimebound]] ptr); // expected-error {{'lifetimebound' attribute only applies to parameters and implicit object parameters}}
22-
static_assert((int [[clang::lifetimebound]]) 12); // expected-error {{cannot be applied to types}}
22+
static_assert((int [[clang::lifetimebound]]) 12); // expected-error {{'lifetimebound' attribute only applies to parameters and implicit object parameters}}
2323
int* attr_on_unnamed_arg(const int& [[clang::lifetimebound]]); // expected-error {{'lifetimebound' attribute only applies to parameters and implicit object parameters}}
2424
template <typename T>
2525
int* attr_on_template_ptr_arg(T * [[clang::lifetimebound]] ptr); // expected-error {{'lifetimebound' attribute only applies to parameters and implicit object parameters}}

0 commit comments

Comments
 (0)