Fix crashes in valueflow#2236
Conversation
http://cppcheck1.osuosl.org:8000/crash.html For instance in http://cppcheck1.osuosl.org:8000/styx ``` ==19651==ERROR: AddressSanitizer: SEGV on unknown address 0x00000000001c (pc 0x556f21abc3df bp 0x7ffc140d2720 sp 0x7ffc140d2710 T0) ==19651==The signal is caused by a READ memory access. ==19651==Hint: address points to the zero page. #0 0x556f21abc3de in Variable::isGlobal() const ../lib/symboldatabase.h:342 #1 0x556f221f801a in valueFlowForwardVariable ../lib/valueflow.cpp:2471 cppcheck-opensource#2 0x556f22208130 in valueFlowForward ../lib/valueflow.cpp:3204 cppcheck-opensource#3 0x556f221e9e14 in valueFlowReverse ../lib/valueflow.cpp:1892 cppcheck-opensource#4 0x556f221f1a43 in valueFlowBeforeCondition ../lib/valueflow.cpp:2200 cppcheck-opensource#5 0x556f2223dbb5 in ValueFlow::setValues(TokenList*, SymbolDatabase*, ErrorLogger*, Settings const*) ../lib/valueflow.cpp:6521 cppcheck-opensource#6 0x556f220e5991 in Tokenizer::simplifyTokens1(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ../lib/tokenize.cpp:2342 cppcheck-opensource#7 0x556f21d8d066 in CppCheck::checkFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream&) ../lib/cppcheck.cpp:508 cppcheck-opensource#8 0x556f21d84cd3 in CppCheck::check(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ../lib/cppcheck.cpp:192 cppcheck-opensource#9 0x556f21a28796 in CppCheckExecutor::check_internal(CppCheck&, int, char const* const*) ../cli/cppcheckexecutor.cpp:884 cppcheck-opensource#10 0x556f21a24be8 in CppCheckExecutor::check(int, char const* const*) ../cli/cppcheckexecutor.cpp:198 cppcheck-opensource#11 0x556f22313063 in main ../cli/main.cpp:95 ```
|
A test would be nice. |
|
Spontaneously... I don't remember any valid reason that |
This happens when the source code is incomplete, like this: void f(struct mailbox *mb)
{
if (mb->x == nullptr) {}
}Cppcheck will assign a varid to |
|
I've reduced one example so that's still causing a SIGSEGV: void SlopeFloor::setAttr(const Value &val) {
int slope = val;
if (slope >= -1)
state = slope;
} |
|
It seems to me that a An attribute can be added that explains the variable has unknown type. We know that for I would suggest that we set the |
I assume that could be a change having a major impact. Maybe we should accept the PR first to get daca@home more stable again. |
|
I think the variable exists but can't be found. The example has a class function without a class defined which means the symbol database is incomplete. Looking up the variable through the class will fail because there is no class but you should still be able to look up the variable though the function. |
|
A variable with an unknown type is common. It will just have a null type pointer. |
ok... if we see a class function implementation but not the class definition... maybe we should stop the analysis and ask the user to fix the include paths. As far as I remember there was tricky problems with that - I have the feeling there is some open ticket. |
|
I looked into this a little deeper. There is a function scope but there is no function because it would be contained in the missing class. Creating a fake class or creating the function in the global scope would be wrong. I think it would cause more problems then it solves. This has been discussed before somewhere. We already have a debug warning for this: although it doesn't really explain the real problem well. |
|
I think this patch is OK but we can now add a test. Hopefully this patch only introduces false negatives. The existing debug warning can be turned into a regular warning explaining that there are probably missing includes and they need to fix that if they want better results. |
|
I have added a test case. |
IMHO it's a very helpful detail of cppcheck that it's to run on incomplete code. At least if one is aware of the risks and shortcoming in that scenario... |
|
I don't think PR has the proper fix. There should be a variable even if the precise type is not known.
Yes of course! But if you have such code in a source file: Then the Handling this without having the class declaration.. I have the feeling it's not as easy as it sounds. I have the feeling we had some ticket somewhere but I can't find it. If we can handle it in a decent way it's better to analyze the code but if we really can't handle that in a way that we feel comfortable with it's better to bailout. |
Thanks @IOBYTE! I have the feeling I also looked at this a few years ago and failed to see any good automated approach for this. If we can make some workaround or good guess for incomplete code that is best! But sometimes it's just not possible. |
|
I merge this anyway.. after all.. I think we can merge this as a temporary hack. |
* Fix crashes in valueflow http://cppcheck1.osuosl.org:8000/crash.html For instance in http://cppcheck1.osuosl.org:8000/styx ``` ==19651==ERROR: AddressSanitizer: SEGV on unknown address 0x00000000001c (pc 0x556f21abc3df bp 0x7ffc140d2720 sp 0x7ffc140d2710 T0) ==19651==The signal is caused by a READ memory access. ==19651==Hint: address points to the zero page. #0 0x556f21abc3de in Variable::isGlobal() const ../lib/symboldatabase.h:342 #1 0x556f221f801a in valueFlowForwardVariable ../lib/valueflow.cpp:2471 cppcheck-opensource#2 0x556f22208130 in valueFlowForward ../lib/valueflow.cpp:3204 cppcheck-opensource#3 0x556f221e9e14 in valueFlowReverse ../lib/valueflow.cpp:1892 cppcheck-opensource#4 0x556f221f1a43 in valueFlowBeforeCondition ../lib/valueflow.cpp:2200 cppcheck-opensource#5 0x556f2223dbb5 in ValueFlow::setValues(TokenList*, SymbolDatabase*, ErrorLogger*, Settings const*) ../lib/valueflow.cpp:6521 cppcheck-opensource#6 0x556f220e5991 in Tokenizer::simplifyTokens1(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ../lib/tokenize.cpp:2342 cppcheck-opensource#7 0x556f21d8d066 in CppCheck::checkFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::istream&) ../lib/cppcheck.cpp:508 cppcheck-opensource#8 0x556f21d84cd3 in CppCheck::check(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) ../lib/cppcheck.cpp:192 cppcheck-opensource#9 0x556f21a28796 in CppCheckExecutor::check_internal(CppCheck&, int, char const* const*) ../cli/cppcheckexecutor.cpp:884 cppcheck-opensource#10 0x556f21a24be8 in CppCheckExecutor::check(int, char const* const*) ../cli/cppcheckexecutor.cpp:198 cppcheck-opensource#11 0x556f22313063 in main ../cli/main.cpp:95 ``` * Add test case for crash in valueflow
http://cppcheck1.osuosl.org:8000/crash.html
For instance in http://cppcheck1.osuosl.org:8000/styx