Skip to content
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

[clang] Improve _Alignas on a struct declaration diagnostic #65638

Merged
merged 1 commit into from
Nov 7, 2023

Conversation

jerinphilip
Copy link
Contributor

@jerinphilip jerinphilip commented Sep 7, 2023

Fixes #58637.

Adds isAlignas() method on AttributeCommonInfo which accounts for
C++ alignas as well as C11 _Alignas.

The method is used to improve diagnostic in C when _Alignas is used in
C at the wrong location. This corrects the previously suggested move
of _Alignas past the declaration specifier, now warns attribute
_Alignas is ignored.

Based on https://reviews.llvm.org/D141177.

@jerinphilip jerinphilip requested a review from a team as a code owner September 7, 2023 16:51
@github-actions github-actions bot added the clang:frontend Language frontend issues, e.g. anything involving "Sema" label Sep 7, 2023
@cor3ntin
Copy link
Contributor

cor3ntin commented Sep 8, 2023

Generally looks good, thanks for working on this

I'd like to see more tests in clang/test/Sema/alignas.c - we don't have a test for struct _Alignas(int) T either apparently.
Given this fixes a bug, it could benefit from a release note in clang/docs/ReleaseNotes.rst

@cor3ntin
Copy link
Contributor

cor3ntin commented Sep 8, 2023

There is similar effort on Phab, we should pick one of them https://reviews.llvm.org/D141177

@cor3ntin
Copy link
Contributor

cor3ntin commented Oct 3, 2023

@AaronBallman you have a preference as to which PR we pursue?

@AaronBallman
Copy link
Collaborator

@AaronBallman you have a preference as to which PR we pursue?

No strong preference, but the author of D141177 seems to have gone silent again so if @jerinphilip is actively working on this patch, I'd say let's go with this one.

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 modulo nitpick.
Maybe @AaronBallman will want to look at it too.
Do we want a release notes for this?

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

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

Thank you for working on this! I think the changes should come with a release note so users know about the fix. I did have a question on the design, but overall the direction seems sensible to me.

@llvmbot llvmbot added the clang Clang issues not falling into any other category label Oct 16, 2023
@jerinphilip jerinphilip force-pushed the alignas_capture__Alignas branch 3 times, most recently from 74b62ef to 919be6b Compare October 22, 2023 18:40
@jerinphilip
Copy link
Contributor Author

jerinphilip commented Oct 22, 2023

I have rebased the PR with main (which appears to fix the formatting workflow). For the time being, I have left the C23 test using alignas in with the active error message and a FIXME.

I've altered the state of this PR to be close to D141177, using the existing attribute warning for reduced complexity (happy to provide attribution). Key difference isAlignas() instead of isC23AlignasAttribute(), thinking the former should be more future-proof. In the current state, isCXX11Attribute() and isStandardAttributeSyntax() is not modified, and the net improvement (in diagnostics) in changes here should be useful when C23 alignas comes in, I hope (I would like to pursue this as a follow-up separate undertaking, if okay).

The following routes were also considered:

  1. Store tok::TokenKind to resolve _Alignas vs alignas. This requires adding one more field to Form and AttributeCommonInfo, while the information is already present via (IsAlignas, SpellingIndex) tuple (This approach is in jerinphilip/llvm-project#1 mixed with other things).
  2. Use calculateAttributeSpellingIndex (also discussed in meeting). This suffers from inability to use AlignedAttr::Keyword_Alignas (clang/AST/Attrs.h) - See #65638 (comment). Absent this, the SpellingIndex value 5 (Keyword_Alignas) will have to be maintained separately here to resolve _Alignas. Looking at the source requires string operations, which are inefficient.

Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

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

Aside from some nits, I think this looks reasonable to me. I'll leave the final sign-off to @erichkeane but if he doesn't approve in the next few days (WG21 meetings are upcoming so he may be busy), I'll come back to approve.

Thank you for all the help on this one! It turns out good first issue is really hard to determine accurately. ;-)

Comment on lines 269 to 294
declaration specifiers.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
declaration specifiers.
declaration specifiers.
(#58637 <https://github.com/llvm/llvm-project/issues/58637>`_)

Comment on lines 5344 to 5351
unsigned DiagnosticId;
if (AL.isAlignas() && !getLangOpts().CPlusPlus) {
DiagnosticId = diag::warn_attribute_ignored;
} else if (AL.isRegularKeywordAttribute()) {
DiagnosticId = diag::err_declspec_keyword_has_no_effect;
} else {
DiagnosticId = diag::warn_declspec_attribute_ignored;
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

Suggested change
unsigned DiagnosticId;
if (AL.isAlignas() && !getLangOpts().CPlusPlus) {
DiagnosticId = diag::warn_attribute_ignored;
} else if (AL.isRegularKeywordAttribute()) {
DiagnosticId = diag::err_declspec_keyword_has_no_effect;
} else {
DiagnosticId = diag::warn_declspec_attribute_ignored;
}
unsigned DiagnosticId = diag::warn_declspec_attribute_ignored;
if (AL.isAlignas() && !getLangOpts().CPlusPlus)
DiagnosticId = diag::warn_attribute_ignored;
else if (AL.isRegularKeywordAttribute())
DiagnosticId = diag::err_declspec_keyword_has_no_effect;

Changes for our odd choice coding style and to be slightly more succinct.

Copy link
Collaborator

@erichkeane erichkeane left a comment

Choose a reason for hiding this comment

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

The comments Aaron made should be fixed, plus 1 more from me, else LGTM.

@@ -192,6 +192,13 @@ class AttributeCommonInfo {

bool isC23Attribute() const { return SyntaxUsed == AS_C23; }

bool isAlignas() const {
// In the current state of code, IsAlignas is only configured to return
Copy link
Collaborator

Choose a reason for hiding this comment

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

This comment is immediately stale once we commit this, right? Also, it refers to IsAlignas, but the function name is isAlignas.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This refers to the variable IsAlignAs (not the parent function isAlignas), and the sentence holds for the current state of code. I believe I'm trying to explain why I cannot use IsAlignas's current behaviour here (as it is more invasive). Normally I'd expect this function to be a const accessor to a private member per programming conventions, which is not the case here, hence a comment.

I'm sensing the review comment confusion indicates I need to communicate this better in source comments. Suggestions welcome.

Copy link
Collaborator

Choose a reason for hiding this comment

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

How about:

// FIXME: In the current state, the IsAlignas member variable is only true with the C++
// `alignas` keyword but not `_Alignas`. The following expression works around the
// otherwise lost information so it will return true for `alignas` or `_Alignas` while still
// returning false for things like `__attribute__((aligned))`.

@jerinphilip jerinphilip force-pushed the alignas_capture__Alignas branch from 919be6b to 323e569 Compare November 1, 2023 20:43
Adds `isAlignas()` method on `AttributeCommonInfo` which accounts for
C++ `alignas` as well as C11 `_Alignas`.

The method is used to improve diagnostic in C when `_Alignas` is used in
C at the wrong location.  This corrects the previously suggested move
of `_Alignas` past the declaration specifier, now warns attribute
`_Alignas` is ignored.
@jerinphilip jerinphilip force-pushed the alignas_capture__Alignas branch from 323e569 to 947d4b4 Compare November 2, 2023 01:51
Copy link
Collaborator

@AaronBallman AaronBallman left a comment

Choose a reason for hiding this comment

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

LGTM! Thank you for the fix!

@AaronBallman AaronBallman merged commit 2e79133 into llvm:main Nov 7, 2023
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.

_Alignas on a struct declaration gives a low-quality diagnostic
5 participants