Skip to content

[clang] Informative error for lifetimebound in decl-spec #118567

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

emaxx-google
Copy link
Contributor

@emaxx-google emaxx-google commented Dec 4, 2024

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.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels Dec 4, 2024
@llvmbot
Copy link
Member

llvmbot commented Dec 4, 2024

@llvm/pr-subscribers-clang

Author: Maksim Ivanov (emaxx-google)

Changes

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.


Full diff: https://github.com/llvm/llvm-project/pull/118567.diff

2 Files Affected:

  • (modified) clang/lib/Parse/ParseDecl.cpp (+8-2)
  • (modified) clang/test/SemaCXX/attr-lifetimebound.cpp (+2-2)
diff --git a/clang/lib/Parse/ParseDecl.cpp b/clang/lib/Parse/ParseDecl.cpp
index 937a94b02458c6..caa1a12297bc01 100644
--- a/clang/lib/Parse/ParseDecl.cpp
+++ b/clang/lib/Parse/ParseDecl.cpp
@@ -3703,8 +3703,14 @@ void Parser::ParseDeclarationSpecifiers(
           // We reject AT_LifetimeBound and AT_AnyX86NoCfCheck, even though they
           // are type attributes, because we historically haven't allowed these
           // to be used as type attributes in C++11 / C23 syntax.
-          if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_LifetimeBound &&
-              PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
+          if (PA.getKind() == ParsedAttr::AT_LifetimeBound) {
+            Diag(PA.getLoc(), diag::err_attribute_wrong_decl_type_str)
+                << PA << PA.isRegularKeywordAttribute()
+                << "parameters and implicit object parameters";
+            PA.setInvalid();
+            continue;
+          }
+          if (PA.isTypeAttr() && PA.getKind() != ParsedAttr::AT_AnyX86NoCfCheck)
             continue;
           Diag(PA.getLoc(), diag::err_attribute_not_type_attr)
               << PA << PA.isRegularKeywordAttribute();
diff --git a/clang/test/SemaCXX/attr-lifetimebound.cpp b/clang/test/SemaCXX/attr-lifetimebound.cpp
index c7abec61873efb..896793f9966666 100644
--- a/clang/test/SemaCXX/attr-lifetimebound.cpp
+++ b/clang/test/SemaCXX/attr-lifetimebound.cpp
@@ -10,7 +10,7 @@ namespace usage_invalid {
     static int *static_class_member() [[clang::lifetimebound]]; // expected-error {{static member function has no implicit object parameter}}
     int *explicit_object(this A&) [[clang::lifetimebound]]; // expected-error {{explicit object member function has no implicit object parameter}}
     int attr_on_var [[clang::lifetimebound]]; // expected-error {{only applies to parameters and implicit object parameters}}
-    int [[clang::lifetimebound]] attr_on_int; // expected-error {{cannot be applied to types}}
+    int [[clang::lifetimebound]] attr_on_int; // expected-error {{'lifetimebound' attribute only applies to parameters and implicit object parameters}}
     int * [[clang::lifetimebound]] attr_on_int_ptr; // expected-error {{'lifetimebound' attribute only applies to parameters and implicit object parameters}}
     int * [[clang::lifetimebound]] * attr_on_int_ptr_ptr; // expected-error {{'lifetimebound' attribute only applies to parameters and implicit object parameters}}
     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 {
   int *attr_with_param(int &param [[clang::lifetimebound(42)]]); // expected-error {{takes no arguments}}
 
   void attr_on_ptr_arg(int * [[clang::lifetimebound]] ptr); // expected-error {{'lifetimebound' attribute only applies to parameters and implicit object parameters}}
-  static_assert((int [[clang::lifetimebound]]) 12); // expected-error {{cannot be applied to types}}
+  static_assert((int [[clang::lifetimebound]]) 12); // expected-error {{'lifetimebound' attribute only applies to parameters and implicit object parameters}}
   int* attr_on_unnamed_arg(const int& [[clang::lifetimebound]]); // expected-error {{'lifetimebound' attribute only applies to parameters and implicit object parameters}}
   template <typename T>
   int* attr_on_template_ptr_arg(T * [[clang::lifetimebound]] ptr); // expected-error {{'lifetimebound' attribute only applies to parameters and implicit object parameters}}

@emaxx-google
Copy link
Contributor Author

@hokein @ilya-biryukov

if (PA.getKind() == ParsedAttr::AT_LifetimeBound) {
Diag(PA.getLoc(), diag::err_attribute_wrong_decl_type_str)
<< PA << PA.isRegularKeywordAttribute()
<< "parameters and implicit object parameters";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we not using %select for that?

Beside, is "implicit object parameters" sufficiently understandable? - or should we say "member functions"?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are we not using %select for that?

Can you explain a bit more? IIUC, you're suggesting using the err_attribute_wrong_decl_type the one with the "%select"? That is possible, but then we'll need to add a new Kind in AttributeDeclKind.

Beside, is "implicit object parameters" sufficiently understandable? - or should we say "member functions"?

I think the implicit object parameter is fine. "member functions" is not entirely correct, the attribute is on the implicit object parameter even though it is applied to a function type in the implementation.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would like to second @cor3ntin's comment. We should aim to have all message strings in one place (i.e. the .td file), it makes searching for error messages much easier.

However, err_attribute_wrong_decl_type_str in particular seems to be using strings in the source code (1, 2, 3).
So I think this change is consistent with that, and I think we should just land it and replace this with a follow-up instead (@emaxx-google would you be willing to do it?)

Adding another AttributeDeclKind seems off, given that it's a enumeration used primarily by parser. But adding a new enumeration for select (that maps to AttributeDeclKind for the known values and adds a few more) seems like a good path forward.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm happy to follow up with the change!

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do see that err_attribute_wrong_decl_type_str uses that same method in other places which is unfortunate. It makes looking for diagnostics a lot harder.

Copy link
Collaborator

@hokein hokein left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The change looks good to me.

Copy link
Contributor

@cor3ntin cor3ntin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM as long as there is a follow up :)

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.
@emaxx-google emaxx-google force-pushed the lifetimebound-warn-cannot-be-applied-to-types branch from cfc2018 to 80c0b2c Compare January 10, 2025 12:35
@hokein hokein merged commit 6b12272 into llvm:main Jan 10, 2025
6 of 7 checks passed
@emaxx-google
Copy link
Contributor Author

#122473 is the promised follow-up for the diag.

BaiXilin pushed a commit to BaiXilin/llvm-fix-vnni-instr-types that referenced this pull request Jan 12, 2025
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.
ilya-biryukov pushed a commit that referenced this pull request Jan 13, 2025
kazutakahirata pushed a commit to kazutakahirata/llvm-project that referenced this pull request Jan 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants