-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Issues handling macros that don't require semicolons #898
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
Conversation
|
The tab parsing test looks like it should be moved to testtokenlist or testtokenize. It does not seem to be symboldatabase related. |
|
You're right. I thought I looked for a better place, but clearly I didn't look hard enough. Sorry, that's just my lack of knowledge of the code base. I've moved the test to testtokenlist.cpp instead and modified it accordingly. |
|
Thanks for these fixes!! I don't believe tokenlist needs to handle the tabs. The Preprocessor does not output tabs as far as I know. Could you show some source file that cause some problem? Macros without semicolon: in such cases we try to tell the user to configure cppcheck better. The function name would probably be "Init" in such code: The severity should be "information". Not sure if you have to use --check-config to see such messages. Feel free to investigate.. |
|
I don't know how you could really configure cppcheck to avoid this issue caused by macros with no semicolons. Even using the Init function declaration you suggest you still get the same warning: I think you might be assuming the macro is in some way related to the function. However, in these cases they are not. It's wxWidgets related macros that just happen to be above the line in question without a semicolon. For instance: class MyWindow : public wxWindow
{
public:
// Insert code here
private:
DECLARE_DYNAMIC_CLASS(MyWindow)
void Init();
};I don't want to disable warnings or uninitMemberVar because we want to catch those. These are just false positives caused by the fact that the macro immediately preceding the Init function causes Init to not make it into the symbolDatabase functionList. So any check that needs to follow Init's logic would be broken. Your code does demonstrate another interesting issue though. My fix would not handle non-macro based pre-processor defines (ie no parenthesis required either) being used immediately before a function call. #define DECLARE_INT int m_int;
struct InitTest
{
InitTest() { Init(); }
private:
DECLARE_INT
void Init() NORETURN THROW(std::exception) { m_var = 0; }
int m_var;
};I can't seem to demonstrate any actual errors caused by the tab parsing from the command line for some reason. However, my original pull request had a unit test in symbol database demonstrating how it caused the function to not show up in the function list if the member function had a tab preceding it because the previous token would be "\tvoid" which wouldn't match what it wanted. If you change the spaces to tabs in the macroFunctionTests I added and revert the tab parsing change then they will fail which is what lead me to fix it. |
|
I see what you mean regarding tabs and the preprocessor now. It makes sense that the unit tests wouldn't involve the preprocessor unless that's what's being tested. I see that's being done in Preprocessor::preprocessWhitespaces. I can remove the commit for the tab changes and just leave the macros tests and fix. |
ah nice... that configuration could be updated a lot. open the cfg/wxwidgets.cfg add this: Then if you run cppcheck with --library=wxwidgets , you should get proper warnings: There is a lot you could configure to get better wxwidgets checking! I hope that sounds interesting. I would love to push some improvements in that file. |
|
Example: |
…nizing member functions if preceded by a macro that does not require a semicolon.
|
I want to have a cfg fix. I am curious if my wxwidgets.cfg fix worked. It's not possible to avoid user configuration here. With your fix the SymbolDatabase will make better guesses in some cases and wrong guesses in other cases. |
|
I really wish there was a better way to handle this because it may mask other issues that I don't know about. I covered the most common macros, but I don't the time to search our code base for all possible macros that could possibly be causing issues. I simply took our cpp.hint file which we use to fix similar issues with macros and Visual Studio intellisense which I just recently discovered and added the same defines. Here is the end result: Note that inside the BEGIN/END macros there are several EVT_* macros for various different types of event handlers. There are way too many different event types for me to define them all. So if I were just to define END_EVENT_TABLE to be replaced by an empty string then the previous EVT_* macro which doesn't end with a semicolon would then cause the same problem so that's why they're replaced with semicolons. |
My solution is not "written in stone". I think it's okay to try to come up with a better solution/configuration.
I think that's an okay approach. Take care of the macros that cause problems for you. This can be extended by others. |
|
I applied your macros with 26ec339. Hope the analysis of your code works better now. |
I added test cases that catch both of these things. However, the original minimal repro causes a false positive uninitMemberVar: