Fixes https://github.com/llvm/llvm-project/issues/61660
Fixed the error message for attribute placement. Earlier it was showing 'place it after "enum"' but it should be 'place it after "enum class"' which I have fixed in this patch.
Details
Diff Detail
- Repository
- rG LLVM Github Monorepo
Event Timeline
- Updating D147989: Fix Attribute Placememt #
- Enter a brief description of the changes included in this update.
clang/lib/Sema/SemaDecl.cpp | ||
---|---|---|
58 | This being global could lead to issues where one overwrites the other. I think a better approach would be to create another version of GetDiagnosticTypeSpecifierID that takes the DeclSpec, then this won't be needed. | |
5309–5314 | if you make a new GetDiagnosticTypeSpecifierID then you can check these conditions in that function instead of there and return 5 if they are all true, otherwise return GetDiagnosticTypeSpecifierID(TypeSpecType). | |
5311–5314 | Then use the new GetDiagnosticTypeSpecifierID here, passing DS instead of TypeSpecType. |
Looping in some people who have worked on and reviewed patches in this area for some experienced eyes.
Thank you for working on this!
The changes are missing test coverage; please be sure to add that, along with a release note about the fix. I think there's likely more work to be done here as well, considering this behavior: https://godbolt.org/z/sdK3Gef75 (notice the suggested location for the fix-it -- that also needs to be fixed for this)
clang/include/clang/Sema/DeclSpec.h | ||
---|---|---|
274 ↗ | (On Diff #512349) | Spurious whitespace change can be removed. |
clang/lib/Sema/SemaDecl.cpp | ||
58 | +1 |
Nothing else to add beyond what @aaron.ballman has noted.
Thanks for working on this!
Thanks for the input Aaron and Martin. This is looking good. With the suggested changes and some formatting I think it will be ready.
clang/include/clang/Sema/DeclSpec.h | ||
---|---|---|
274 ↗ | (On Diff #512421) | There is still a whitespace change here. |
clang/lib/Sema/SemaDecl.cpp | ||
5046–5054 | Thanks to C++ overloading, this can be called GetDiagnosticTypeSpecifierID, and I don't think it will need the T parameter since that can be fetched with DS.getTypeSpecType(). |
clang/include/clang/Basic/DiagnosticSemaKinds.td | ||
---|---|---|
3424 | "enum struct" is also possible in C++, so I think this needs to be covered as well. |
Precommit CI has several failures introduced by this patch -- some test cases need to be fixed up (in addition to the new test coverage).
clang/include/clang/Basic/DiagnosticSemaKinds.td | ||
---|---|---|
3424 | If that turns out to be frustrating for some reason, we could perhaps reuse class or struct instead of adding enum <X> as another option. e.g., __attribute__((whatever)) // warning: attribute 'whatever' is ignored, place it after "class" to apply attribute to type declaration enum class foo { }; coupled with the insert caret and fix-it hint, it's pretty clear where to move the attribute to despite the warning not saying enum class specifically. |
Can you please provide me guidance for writing tests for enum class. As I have tried but I am not getting any idea on how to write new tests for enum class.
clang/lib/Sema/SemaDecl.cpp | ||
---|---|---|
5041 | Ya, we can do that too. But like GetDiagnosticTypeSpecifierID() is also called in many other places in the file so if I pass the full DeclSpec in this function will not disturb those calls? |
clang/lib/Sema/SemaDecl.cpp | ||
---|---|---|
5051 | Instead of returning 4 here, I think it's best to just delegate to the other GetDiagnosticTypeSpecifierID function. That way, if the IDs change for whatever reason they only have to updated in one place. This could be done cleanly by just making the call below be at the top level of the function (i.e. not inside an else block). |
clang/lib/Sema/SemaDecl.cpp | ||
---|---|---|
5041 | It's probably worth doing as the other callsites just pass the DeclSpec's type specifier. |
This looks good to me now, nice work. Let's wait a few days for others' input to be safe.
okay! Thank You Sir.
clang/lib/Sema/SemaDecl.cpp | ||
---|---|---|
5051 | Ya that can be done. I will do it. |
Thank you for working on this! I spotted a little more that needs to be done, but this is pretty close to ready. I *think* the precommit CI failures are unrelated to this change, but you should double-check just to be sure.
clang/lib/Sema/SemaDecl.cpp | ||
---|---|---|
5031 | Style nit; NFC | |
5041–5045 | There's a subtle bug hiding in here, consider code like: __attribute__((visibility("hidden"))) __attribute__((aligned)) enum struct E {}; The diagnostic will emit enum because the EnumDecl is scoped using the struct tag rather than the class tag. I think you should add another entry to the %select for enum struct and return that value here if ED->isScoped() is true, and only return 4 for a plain enum. | |
clang/test/Sema/attr-declspec-ignored.c | ||
23 | I'm not seeing what changed with this line, I think you can revert the changes to this file. | |
clang/test/SemaCXX/attr-declspec-ignored.cpp | ||
12 | Once you fix the enum struct diagnostic above, I'd recommend adding some enum struct test cases. |
Do you need someone to land this on your behalf? If so, what name and email address would you like used for patch attribution? (I can fix the tiny style nit myself when landing, so don't feel obligated to make the change yourself unless you're committing the patch.)
clang/lib/Sema/SemaDecl.cpp | ||
---|---|---|
5044 | Tiny style nit; NFC (we have a rule about using else after a return). |
Oops, I spoke too soon -- it looks like the precommit CI failure is related to this patch. This is what I get when I tested locally:
Assertion failed: NextVal != ArgumentEnd && "Value for integer select modifier was" " larger than the number of options in the diagnostic string!", file F:\source\llvm-project\clang\lib\Basic\Diagnostic.cpp, line 623 PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script. Stack dump: 0. Program arguments: f:\\source\\llvm-project\\llvm\\out\\build\\x64-debug\\bin\\clang.exe -cc1 -internal-isystem f:\\source\\llvm-project\\llvm\\out\\build\\x64-debug\\lib\\clang\\17\\include -nostdsysteminc -std=c++11 -triple x86_64-unknown-unknown F:\\source\\llvm-project\\clang\\test\\CXX\\drs\\dr16xx.cpp -verify -fexceptions -fcxx-exceptions -pedantic-errors 1. F:\source\llvm-project\clang\test\CXX\drs\dr16xx.cpp:91:3: current parser token 'template' 2. F:\source\llvm-project\clang\test\CXX\drs\dr16xx.cpp:71:1: parsing namespace 'dr1638' Exception Code: 0x80000003 #0 0x00007ff6625ea26c HandleAbort F:\source\llvm-project\llvm\lib\Support\Windows\Signals.inc:419:0 #1 0x00007ffa9b23bc31 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x6bc31) #2 0x00007ffa9b23d889 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x6d889) #3 0x00007ffa9b2430bf (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x730bf) #4 0x00007ffa9b241091 (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x71091) #5 0x00007ffa9b243a1f (C:\WINDOWS\SYSTEM32\ucrtbased.dll+0x73a1f) #6 0x00007ff662a19b8c HandleSelectModifier F:\source\llvm-project\clang\lib\Basic\Diagnostic.cpp:622:0 #7 0x00007ff662a17137 clang::Diagnostic::FormatDiagnostic(char const *, char const *, class llvm::SmallVectorImpl<char> &) const F:\source\llvm-project\clang\lib\Basic\Diagnostic.cpp:1005:0 #8 0x00007ff662a16518 clang::Diagnostic::FormatDiagnostic(class llvm::SmallVectorImpl<char> &) const F:\source\llvm-project\clang\lib\Basic\Diagnostic.cpp:805:0 #9 0x00007ff663e5bcc9 clang::TextDiagnosticBuffer::HandleDiagnostic(enum clang::DiagnosticsEngine::Level, class clang::Diagnostic const &) F:\source\llvm-project\clang\lib\Frontend\TextDiagnosticBuffer.cpp:30:0 #10 0x00007ff663ef2d71 clang::VerifyDiagnosticConsumer::HandleDiagnostic(enum clang::DiagnosticsEngine::Level, class clang::Diagnostic const &) F:\source\llvm-project\clang\lib\Frontend\VerifyDiagnosticConsumer.cpp:757:0 #11 0x00007ff662a0b66f clang::DiagnosticIDs::EmitDiag(class clang::DiagnosticsEngine &, enum clang::DiagnosticIDs::Level) const F:\source\llvm-project\clang\lib\Basic\DiagnosticIDs.cpp:839:0 #12 0x00007ff662a0b597 clang::DiagnosticIDs::ProcessDiag(class clang::DiagnosticsEngine &) const F:\source\llvm-project\clang\lib\Basic\DiagnosticIDs.cpp:831:0 #13 0x00007ff662a267ef clang::DiagnosticsEngine::ProcessDiag(void) F:\source\llvm-project\clang\include\clang\Basic\Diagnostic.h:1038:0 #14 0x00007ff662a15f64 clang::DiagnosticsEngine::EmitCurrentDiagnostic(bool) F:\source\llvm-project\clang\lib\Basic\Diagnostic.cpp:549:0 #15 0x00007ff667b47cbc clang::Sema::EmitCurrentDiagnostic(unsigned int) F:\source\llvm-project\clang\lib\Sema\Sema.cpp:1575:0 #16 0x00007ff667b89d97 clang::Sema::ImmediateDiagBuilder::~ImmediateDiagBuilder(void) F:\source\llvm-project\clang\include\clang\Sema\Sema.h:1726:0 #17 0x00007ff667b8e9e8 clang::Sema::ImmediateDiagBuilder::`scalar deleting dtor'(unsigned int) (f:\source\llvm-project\llvm\out\build\x64-debug\bin\clang.exe+0x81fe9e8) #18 0x00007ff667b72b06 std::_Destroy_in_place<class clang::Sema::ImmediateDiagBuilder>(class clang::Sema::ImmediateDiagBuilder &) C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.35.32215\include\xmemory:300:0 #19 0x00007ff667bac5b4 std::_Optional_destruct_base<class clang::Sema::ImmediateDiagBuilder, 0>::reset(void) C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Tools\MSVC\14.35.32215\include\optional:133:0 #20 0x00007ff667b53424 clang::Sema::SemaDiagnosticBuilder::~SemaDiagnosticBuilder(void) F:\source\llvm-project\clang\lib\Sema\Sema.cpp:1859:0 #21 0x00007ff668618b4a clang::Sema::ParsedFreeStandingDeclSpec(class clang::Scope *, enum clang::AccessSpecifier, class clang::DeclSpec &, class clang::ParsedAttributesView const &, class llvm::MutableArrayRef<class clang::TemplateParameterList *>, bool, class clang::RecordDecl *&) F:\source\llvm-project\clang\lib\Sema\SemaDecl.cpp:5151:0 #22 0x00007ff668618545 clang::Sema::ParsedFreeStandingDeclSpec(class clang::Scope *, enum clang::AccessSpecifier, class clang::DeclSpec &, class clang::ParsedAttributesView const &, class clang::RecordDecl *&) F:\source\llvm-project\clang\lib\Sema\SemaDecl.cpp:4844:0 #23 0x00007ff66797e8e2 clang::Parser::ParseDeclOrFunctionDefInternal(class clang::ParsedAttributes &, class clang::ParsedAttributes &, class clang::ParsingDeclSpec &, enum clang::AccessSpecifier) F:\source\llvm-project\clang\lib\Parse\Parser.cpp:1160:0 #24 0x00007ff66797e532 clang::Parser::ParseDeclarationOrFunctionDefinition(class clang::ParsedAttributes &, class clang::ParsedAttributes &, class clang::ParsingDeclSpec *, enum clang::AccessSpecifier) F:\source\llvm-project\clang\lib\Parse\Parser.cpp:1228:0 #25 0x00007ff66797de7d clang::Parser::ParseExternalDeclaration(class clang::ParsedAttributes &, class clang::ParsedAttributes &, class clang::ParsingDeclSpec *) F:\source\llvm-project\clang\lib\Parse\Parser.cpp:1043:0 #26 0x00007ff667ac8745 clang::Parser::ParseInnerNamespace(class llvm::SmallVector<struct clang::Parser::InnerNamespaceInfo, 4> const &, unsigned int, class clang::SourceLocation &, class clang::ParsedAttributes &, class clang::BalancedDelimiterTracker &) F:\source\llvm-project\clang\lib\Parse\ParseDeclCXX.cpp:262:0 #27 0x00007ff667ac84b5 clang::Parser::ParseNamespace(enum clang::DeclaratorContext, class clang::SourceLocation &, class clang::SourceLocation) F:\source\llvm-project\clang\lib\Parse\ParseDeclCXX.cpp:241:0 #28 0x00007ff6679ce5af clang::Parser::ParseDeclaration(enum clang::DeclaratorContext, class clang::SourceLocation &, class clang::ParsedAttributes &, class clang::ParsedAttributes &, class clang::SourceLocation *) F:\source\llvm-project\clang\lib\Parse\ParseDecl.cpp:1846:0 #29 0x00007ff66797d768 clang::Parser::ParseExternalDeclaration(class clang::ParsedAttributes &, class clang::ParsedAttributes &, class clang::ParsingDeclSpec *) F:\source\llvm-project\clang\lib\Parse\Parser.cpp:959:0 #30 0x00007ff667977257 clang::Parser::ParseTopLevelDecl(class clang::OpaquePtr<class clang::DeclGroupRef> &, enum clang::Sema::ModuleImportState &) F:\source\llvm-project\clang\lib\Parse\Parser.cpp:745:0 #31 0x00007ff66797277d clang::ParseAST(class clang::Sema &, bool, bool) F:\source\llvm-project\clang\lib\Parse\ParseAST.cpp:162:0 #32 0x00007ff663ea922a clang::ASTFrontendAction::ExecuteAction(void) F:\source\llvm-project\clang\lib\Frontend\FrontendAction.cpp:1168:0 #33 0x00007ff663ea8b3e clang::FrontendAction::Execute(void) F:\source\llvm-project\clang\lib\Frontend\FrontendAction.cpp:1060:0 #34 0x00007ff663e207c8 clang::CompilerInstance::ExecuteAction(class clang::FrontendAction &) F:\source\llvm-project\clang\lib\Frontend\CompilerInstance.cpp:1049:0 #35 0x00007ff6640ebe80 clang::ExecuteCompilerInvocation(class clang::CompilerInstance *) F:\source\llvm-project\clang\lib\FrontendTool\ExecuteCompilerInvocation.cpp:264:0 #36 0x00007ff65fdaa7e4 cc1_main(class llvm::ArrayRef<char const *>, char const *, void *) F:\source\llvm-project\clang\tools\driver\cc1_main.cpp:251:0 #37 0x00007ff65fd8becb ExecuteCC1Tool F:\source\llvm-project\clang\tools\driver\driver.cpp:366:0 #38 0x00007ff65fd8c719 clang_main(int, char **, struct llvm::ToolContext const &) F:\source\llvm-project\clang\tools\driver\driver.cpp:407:0 #39 0x00007ff65fdd8bf6 main F:\source\llvm-project\llvm\out\build\x64-Debug\tools\clang\tools\driver\clang-driver.cpp:16:0 #40 0x00007ff66b6cd929 invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:79:0 #41 0x00007ff66b6cd7ce __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288:0 #42 0x00007ff66b6cd68e __scrt_common_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:331:0 #43 0x00007ff66b6cd9be mainCRTStartup D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_main.cpp:17:0 #44 0x00007ffb71d27604 (C:\WINDOWS\System32\KERNEL32.DLL+0x17604) #45 0x00007ffb721026a1 (C:\WINDOWS\SYSTEM32\ntdll.dll+0x526a1) error: command failed with exit status: 0x80000003 -- ******************** Testing: 0.. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90.. ******************** Failed Tests (1): Clang :: CXX/drs/dr16xx.cpp
Ohh! I am not getting why these errors are occurring. Can you please help me to solve these errors?
The issue is that GetDiagnosticTypeSpecifierID() is called for more diagnostics than just warn_declspec_attribute_ignored. You need to also update the err_constexpr_tag and err_standalone_class_nested_name_specifier to add enum class and enum struct as well.
LGTM! Do you need someone to land this on your behalf? If so, what name and email address would you like used for patch attribution?
Yes, I need someone who can commit it for me.
Username: ipriyanshi1708
Email address: priyanshiagarwal1708@gmail.com
Please commit it for me.
"enum struct" is also possible in C++, so I think this needs to be covered as well.