cppcoreguidelines-prefer-member-initializer crashes on classes declared inside macros (see bug 47778). This patch fixes this issue.
Details
Diff Detail
Event Timeline
Thanks for the fix! However, I'm not sure it's possible to correctly rewrite code in all cases where macros are involved. See a couple of motivating examples in the comment.
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-prefer-member-initializer.cpp | ||
---|---|---|
498 | Could you add tests where the field name comes from a macro argument and from token pasting? Something along the lines of: #define MACRO4(field) struct InMacro1 { int field; InMacro1() { field = 0; } } MACRO4(q); #define MACRO5(X) X MACRO5(struct InMacro1 { int field; InMacro1() { field = 0; } }); #define MACRO6(field) struct InMacro1 { int qqq ## field; InMacro1() { qqq ## field = 0; } } MACRO6(q); |
clang-tools-extra/clang-tidy/cppcoreguidelines/PreferMemberInitializerCheck.cpp | ||
---|---|---|
169 | Looks like clang-format is not happy with a number of places in the file. Could you git clang-format the patch? (Or just clang-format the whole file - maybe in a separate commit - if you don't have the git integration handy.) |
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-prefer-member-initializer.cpp | ||
---|---|---|
498 | It seems that handling of macro parameters in the SourceManager is totally off. The location in these cases are the macro call itself, but the spelling location is not the real location inside the macro, but in MACRO4 it is the location of the argument still in the macro call. The case with MACRO6 is even worse, because its spelling location is erroneous. So I could only added some fixmes. However, it does not crash, at least. That is the main intention of this particular patch. |
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-prefer-member-initializer.cpp | ||
---|---|---|
498 | It's impossible to correctly handle replacements in all cases involving macros (apart from expanding all macros while applying fixes ;). The usual strategy is to warn always, but only suggest replacements when we can be sufficiently confident in their validity. In this case we can either disable fixes when any part of the code being touched is in a macro or try to detect that the whole range being modified is sort of "on the same level of macro hell". The Lexer::makeFileCharRange is supposed to help with the latter (see clang-tools-extra/clang-tidy/modernize/UseOverrideCheck.cpp for an example of using it). |
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-prefer-member-initializer.cpp | ||
---|---|---|
498 | Actually, this is what the patch does: it does not suggest a fix in complex macro cases, only in the simplest ones. And most importantly, it prevents the crash mentioned in the Bugzilla bug report. |
clang-tools-extra/test/clang-tidy/checkers/cppcoreguidelines-prefer-member-initializer.cpp | ||
---|---|---|
6 | "results in ..." | |
6 | The reason is that token pasting is used in the macro. There is no place in any of the existing source files where the text of the token that is created by token pasting exists (verbatim and contiguously). | |
7 | "being"? | |
500 | Please add CHECK-FIXES: for the macro usage (unchanged, I suppose?). Same below. | |
514–515 | Do we need these disabled check lines? If so, please mention the reason in a comment. Same below. |
Looks like clang-format is not happy with a number of places in the file. Could you git clang-format the patch? (Or just clang-format the whole file - maybe in a separate commit - if you don't have the git integration handy.)