negative array size: fixed noise when array is not vla

This commit is contained in:
Daniel Marjamäki 2015-07-04 09:42:42 +02:00
parent 7e1ddea653
commit fef251ac76
2 changed files with 37 additions and 3 deletions

View File

@ -31,6 +31,7 @@
#include <list> #include <list>
#include <cassert> // <- assert #include <cassert> // <- assert
#include <cstdlib> #include <cstdlib>
#include <stack>
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -978,6 +979,32 @@ void CheckBufferOverrun::checkScope(const Token *tok, const ArrayInfo &arrayInfo
// Negative size in array declarations // Negative size in array declarations
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static bool isVLAIndex(const Token *index)
{
std::stack<const Token *> tokens;
tokens.push(index);
while (!tokens.empty()) {
const Token *tok = tokens.top();
tokens.pop();
if (!tok)
continue;
if (tok->varId() != 0U)
return true;
if (tok->str() == "?") {
// this is a VLA index if both expressions around the ":" is VLA index
if (tok->astOperand2() &&
tok->astOperand2()->str() == ":" &&
isVLAIndex(tok->astOperand2()->astOperand1()) &&
isVLAIndex(tok->astOperand2()->astOperand2()))
return true;
continue;
}
tokens.push(tok->astOperand1());
tokens.push(tok->astOperand2());
}
return false;
}
void CheckBufferOverrun::negativeArraySize() void CheckBufferOverrun::negativeArraySize()
{ {
const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase(); const SymbolDatabase* symbolDatabase = _tokenizer->getSymbolDatabase();
@ -989,8 +1016,8 @@ void CheckBufferOverrun::negativeArraySize()
if (!Token::Match(nameToken, "%var% [") || !nameToken->next()->astOperand2()) if (!Token::Match(nameToken, "%var% [") || !nameToken->next()->astOperand2())
continue; continue;
const ValueFlow::Value *sz = nameToken->next()->astOperand2()->getValueLE(-1,_settings); const ValueFlow::Value *sz = nameToken->next()->astOperand2()->getValueLE(-1,_settings);
if (!sz) // don't warn about constant negative index because that is a compiler error
continue; if (sz && isVLAIndex(nameToken->next()->astOperand2()))
negativeArraySizeError(nameToken); negativeArraySizeError(nameToken);
} }
} }

View File

@ -3820,6 +3820,13 @@ private:
"}\n" "}\n"
"void x() { f(-100); }"); "void x() { f(-100); }");
ASSERT_EQUALS("[test.cpp:2]: (error) Declaration of array 'a' with negative size is undefined behaviour\n", errout.str()); ASSERT_EQUALS("[test.cpp:2]: (error) Declaration of array 'a' with negative size is undefined behaviour\n", errout.str());
// don't warn for constant sizes -> this is a compiler error so this is used for static assertions for instance
check("int x, y;\n"
"int a[-1];\n"
"int b[x?1:-1];\n"
"int c[x?y:-1];\n");
ASSERT_EQUALS("", errout.str());
} }
void garbage1() { void garbage1() {