negative array size: fixed noise when array is not vla
This commit is contained in:
parent
7e1ddea653
commit
fef251ac76
|
@ -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,9 +1016,9 @@ 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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() {
|
||||||
|
|
Loading…
Reference in New Issue