#6981 crash in checkvaarg.cpp (with possible fix). Avoid segfault. Add SymbolDatabase::validate() to allow validating smyboldatabase
This commit is contained in:
parent
5ddc5c0798
commit
ba0859e838
|
@ -40,6 +40,8 @@ void CheckVaarg::va_start_argument()
|
|||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope* scope = symbolDatabase->functionScopes[i];
|
||||
const Function* function = scope->function;
|
||||
if (!function)
|
||||
continue;
|
||||
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
if (!tok->scope()->isExecutable())
|
||||
tok = tok->scope()->classEnd;
|
||||
|
|
|
@ -1425,6 +1425,25 @@ bool SymbolDatabase::isFunction(const Token *tok, const Scope* outerScope, const
|
|||
return false;
|
||||
}
|
||||
|
||||
void SymbolDatabase::validate() const
|
||||
{
|
||||
const std::size_t functions = functionScopes.size();
|
||||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope* scope = functionScopes[i];
|
||||
if (scope->isExecutable()) {
|
||||
const Function* function = scope->function;
|
||||
if (!function) {
|
||||
cppcheckError(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SymbolDatabase::cppcheckError(const Token *tok) const
|
||||
{
|
||||
throw InternalError(tok, "Analysis failed. If the code is valid then please report this failure.", InternalError::INTERNAL);
|
||||
}
|
||||
|
||||
bool Variable::isPointerArray() const
|
||||
{
|
||||
return isArray() && nameToken() && nameToken()->previous() && (nameToken()->previous()->str() == "*");
|
||||
|
|
|
@ -1007,6 +1007,11 @@ public:
|
|||
|
||||
bool isCPP() const;
|
||||
|
||||
/*
|
||||
* @brief Do a sanity check
|
||||
*/
|
||||
void validate() const;
|
||||
|
||||
/** Set valuetype in provided tokenlist */
|
||||
static void setValueTypeInTokenList(Token *tokens);
|
||||
|
||||
|
@ -1022,6 +1027,11 @@ private:
|
|||
const Type *findTypeInNested(const Token *tok, const Scope *startScope) const;
|
||||
const Scope *findNamespace(const Token * tok, const Scope * scope) const;
|
||||
Function *findFunctionInScope(const Token *func, const Scope *ns);
|
||||
/**
|
||||
* Send error message to error logger about internal bug.
|
||||
* @param tok the token that this bug concerns.
|
||||
*/
|
||||
void cppcheckError(const Token *tok) const __attribute__((noreturn));
|
||||
|
||||
/** Whether iName is a keyword as defined in http://en.cppreference.com/w/c/keyword and http://en.cppreference.com/w/cpp/keyword*/
|
||||
bool isReservedName(const std::string& iName) const;
|
||||
|
|
|
@ -9840,6 +9840,8 @@ void Tokenizer::createSymbolDatabase()
|
|||
{
|
||||
if (!_symbolDatabase)
|
||||
_symbolDatabase = new SymbolDatabase(this, _settings, _errorLogger);
|
||||
if (_settings->debug)
|
||||
_symbolDatabase->validate();
|
||||
}
|
||||
|
||||
void Tokenizer::deleteSymbolDatabase()
|
||||
|
|
|
@ -1982,7 +1982,7 @@ static void valueFlowForLoopSimplify(Token * const bodyStart, const unsigned int
|
|||
break;
|
||||
if (parent->str() == "?") {
|
||||
if (parent->astOperand2() != p)
|
||||
parent = NULL;
|
||||
parent = nullptr;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -446,7 +446,7 @@ private:
|
|||
|
||||
void testautovar_return2() {
|
||||
check("class Fred {\n"
|
||||
" int* func1()\n"
|
||||
" int* func1();\n"
|
||||
"}\n"
|
||||
"int* Fred::func1()\n"
|
||||
"{\n"
|
||||
|
@ -876,7 +876,6 @@ private:
|
|||
" return foo();\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// Don't crash with function in unknown scope (#4076)
|
||||
check("X& a::Bar() {}"
|
||||
"X& foo() {"
|
||||
|
|
|
@ -50,6 +50,7 @@ private:
|
|||
TEST_CASE(va_end_missing);
|
||||
TEST_CASE(va_list_usedBeforeStarted);
|
||||
TEST_CASE(va_start_subsequentCalls);
|
||||
TEST_CASE(unknownFunctionScope);
|
||||
}
|
||||
|
||||
void wrongParameterTo_va_start() {
|
||||
|
@ -227,6 +228,15 @@ private:
|
|||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void unknownFunctionScope() {
|
||||
check("void BG_TString::Format() {\n"
|
||||
" BG_TChar * f;\n"
|
||||
" va_start(args,f);\n"
|
||||
" BG_TString result(f);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_TEST(TestVaarg)
|
||||
|
|
Loading…
Reference in New Issue