speed up checks by caching commonly looked up stuff in the symbol database (CheckOther). Ticket #4266
This commit is contained in:
parent
6578b78077
commit
04d04c33c2
|
@ -40,8 +40,10 @@ void CheckOther::checkIncrementBoolean()
|
|||
return;
|
||||
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
if (Token::Match(tok, "%var% ++")) {
|
||||
if (tok->varId()) {
|
||||
const Variable *var = symbolDatabase->getVariableFromVarId(tok->varId());
|
||||
|
@ -52,6 +54,7 @@ void CheckOther::checkIncrementBoolean()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::incrementBooleanError(const Token *tok)
|
||||
{
|
||||
|
@ -71,8 +74,12 @@ void CheckOther::clarifyCalculation()
|
|||
if (!_settings->isEnabled("style"))
|
||||
return;
|
||||
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||
if (tok->str() == "?" && tok->previous()) {
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
if (tok->str() == "?") {
|
||||
// condition
|
||||
const Token *cond = tok->previous();
|
||||
if (cond->isName() || cond->isNumber())
|
||||
|
@ -118,6 +125,7 @@ void CheckOther::clarifyCalculation()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::clarifyCalculationError(const Token *tok, const std::string &op)
|
||||
{
|
||||
|
@ -149,7 +157,11 @@ void CheckOther::clarifyCondition()
|
|||
|
||||
const bool isC = _tokenizer->isC();
|
||||
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
if (Token::Match(tok, "( %var% [=&|^]")) {
|
||||
for (const Token *tok2 = tok->tokAt(3); tok2; tok2 = tok2->next()) {
|
||||
if (tok2->str() == "(" || tok2->str() == "[")
|
||||
|
@ -166,9 +178,12 @@ void CheckOther::clarifyCondition()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// using boolean result in bitwise operation ! x [&|^]
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
if (Token::Match(tok, "!|<|<=|==|!=|>|>=")) {
|
||||
if (tok->link()) // don't write false positives when templates are used
|
||||
continue;
|
||||
|
@ -206,6 +221,7 @@ void CheckOther::clarifyCondition()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::clarifyConditionError(const Token *tok, bool assign, bool boolop)
|
||||
{
|
||||
|
@ -237,7 +253,11 @@ void CheckOther::clarifyStatement()
|
|||
if (!_settings->isEnabled("style"))
|
||||
return;
|
||||
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||
for (const Token* tok = scope->classStart; tok != scope->classEnd; tok = tok->next()) {
|
||||
if (Token::Match(tok, "* %var%")) {
|
||||
const Token *tok2=tok->previous();
|
||||
|
||||
|
@ -264,6 +284,7 @@ void CheckOther::clarifyStatement()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::clarifyStatementError(const Token *tok)
|
||||
{
|
||||
|
@ -286,7 +307,11 @@ void CheckOther::checkBitwiseOnBoolean()
|
|||
if (!_settings->inconclusive)
|
||||
return;
|
||||
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
if (Token::Match(tok, "(|.|return|&&|%oror%|throw|, %var% [&|]")) {
|
||||
const Variable *var = _tokenizer->getSymbolDatabase()->getVariableFromVarId(tok->next()->varId());
|
||||
if (var && var->typeEndToken()->str() == "bool") {
|
||||
|
@ -302,6 +327,7 @@ void CheckOther::checkBitwiseOnBoolean()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::bitwiseOnBooleanError(const Token *tok, const std::string &varname, const std::string &op)
|
||||
{
|
||||
|
@ -393,18 +419,22 @@ void CheckOther::invalidPointerCast()
|
|||
if (!_settings->isEnabled("style") && !_settings->isEnabled("portability"))
|
||||
return;
|
||||
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||
const SymbolDatabase* const symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
const Token* toTok = 0;
|
||||
const Token* nextTok = 0;
|
||||
// Find cast
|
||||
if (Token::Match(tok, "( const| %type% const| * )") || Token::Match(tok, "( const| %type% %type% const| * )")) {
|
||||
if (Token::Match(tok, "( const| %type% const| * )") ||
|
||||
Token::Match(tok, "( const| %type% %type% const| * )")) {
|
||||
toTok = tok->next();
|
||||
nextTok = tok->link()->next();
|
||||
if (nextTok && nextTok->str() == "(")
|
||||
nextTok = nextTok->next();
|
||||
} else if (Token::Match(tok, "reinterpret_cast < const| %type% const| * > (") || Token::Match(tok, "reinterpret_cast < const| %type% %type% const| * > (")) {
|
||||
} else if (Token::Match(tok, "reinterpret_cast < const| %type% const| * > (") ||
|
||||
Token::Match(tok, "reinterpret_cast < const| %type% %type% const| * > (")) {
|
||||
nextTok = tok->tokAt(5);
|
||||
while (nextTok->str() != "(")
|
||||
nextTok = nextTok->next();
|
||||
|
@ -452,6 +482,7 @@ void CheckOther::invalidPointerCast()
|
|||
invalidPointerCastError(tok, fromType, toType, toTok->str() == "char");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::invalidPointerCastError(const Token* tok, const std::string& from, const std::string& to, bool inconclusive)
|
||||
{
|
||||
|
@ -471,14 +502,18 @@ void CheckOther::checkSizeofForNumericParameter()
|
|||
if (!_settings->isEnabled("style"))
|
||||
return;
|
||||
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||
if (Token::Match(tok, "sizeof ( %num% )")
|
||||
|| Token::Match(tok, "sizeof %num%")
|
||||
) {
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
if (Token::Match(tok, "sizeof ( %num% )") ||
|
||||
Token::Match(tok, "sizeof %num%")) {
|
||||
sizeofForNumericParameterError(tok);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::sizeofForNumericParameterError(const Token *tok)
|
||||
{
|
||||
|
@ -494,9 +529,12 @@ void CheckOther::sizeofForNumericParameterError(const Token *tok)
|
|||
void CheckOther::checkSizeofForArrayParameter()
|
||||
{
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||
if (Token::Match(tok, "sizeof ( %var% )") || Token::Match(tok, "sizeof %var% !![")) {
|
||||
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||
for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) {
|
||||
if (Token::Match(tok, "sizeof ( %var% )") ||
|
||||
Token::Match(tok, "sizeof %var% !![")) {
|
||||
const Token* varTok = tok->next();
|
||||
if (varTok->str() == "(") {
|
||||
varTok = varTok->next();
|
||||
|
@ -510,6 +548,7 @@ void CheckOther::checkSizeofForArrayParameter()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::sizeofForArrayParameterError(const Token *tok)
|
||||
{
|
||||
|
@ -529,12 +568,14 @@ void CheckOther::sizeofForArrayParameterError(const Token *tok)
|
|||
|
||||
void CheckOther::checkSizeofForPointerSize()
|
||||
{
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
|
||||
if (!_settings->isEnabled("style"))
|
||||
return;
|
||||
|
||||
for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) {
|
||||
const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase();
|
||||
const std::size_t functions = symbolDatabase->functionScopes.size();
|
||||
for (std::size_t i = 0; i < functions; ++i) {
|
||||
const Scope * scope = symbolDatabase->functionScopes[i];
|
||||
for (const Token* tok = scope->classStart; tok != scope->classEnd; tok = tok->next()) {
|
||||
const Token *tokVar;
|
||||
const Token *variable;
|
||||
const Token *variable2 = 0;
|
||||
|
@ -606,6 +647,7 @@ void CheckOther::checkSizeofForPointerSize()
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CheckOther::sizeofForPointerError(const Token *tok, const std::string &varname)
|
||||
{
|
||||
|
|
|
@ -4578,11 +4578,11 @@ private:
|
|||
|
||||
void incrementBoolean() {
|
||||
check("bool bValue = true;\n"
|
||||
"bValue++;\n");
|
||||
"void f() { bValue++; }\n");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Incrementing a variable of type 'bool' with postfix operator++ is deprecated by the C++ Standard. You should assign it the value 'true' instead.\n", errout.str());
|
||||
|
||||
check("_Bool bValue = true;\n"
|
||||
"bValue++;\n");
|
||||
"void f() { bValue++; }\n");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (style) Incrementing a variable of type 'bool' with postfix operator++ is deprecated by the C++ Standard. You should assign it the value 'true' instead.\n", errout.str());
|
||||
|
||||
check("void f(bool test){\n"
|
||||
|
@ -5253,154 +5253,182 @@ private:
|
|||
}
|
||||
|
||||
void checkPointerSizeof() {
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" char *x = malloc(10);\n"
|
||||
"free(x);");
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(sizeof(*x));\n"
|
||||
"free(x);");
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(sizeof(int));\n"
|
||||
"free(x);");
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(sizeof(x));\n"
|
||||
"free(x);");
|
||||
ASSERT_EQUALS("[test.cpp:1]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(sizeof(&x));\n"
|
||||
"free(x);");
|
||||
ASSERT_EQUALS("[test.cpp:1]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(100 * sizeof(x));\n"
|
||||
"free(x);");
|
||||
ASSERT_EQUALS("[test.cpp:1]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(sizeof(x) * 100);\n"
|
||||
"free(x);");
|
||||
ASSERT_EQUALS("[test.cpp:1]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(sizeof *x);\n"
|
||||
"free(x);");
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(sizeof x);\n"
|
||||
"free(x);");
|
||||
ASSERT_EQUALS("[test.cpp:1]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(100 * sizeof x);\n"
|
||||
"free(x);");
|
||||
ASSERT_EQUALS("[test.cpp:1]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = calloc(1, sizeof(*x));\n"
|
||||
"free(x);");
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = calloc(1, sizeof *x);\n"
|
||||
"free(x);");
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = calloc(1, sizeof(x));\n"
|
||||
"free(x);");
|
||||
ASSERT_EQUALS("[test.cpp:1]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = calloc(1, sizeof x);\n"
|
||||
"free(x);");
|
||||
ASSERT_EQUALS("[test.cpp:1]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = calloc(1, sizeof(int));\n"
|
||||
"free(x);");
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" char x[10];\n"
|
||||
"memset(x, 0, sizeof(x));");
|
||||
" memset(x, 0, sizeof(x));\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" char* x[10];\n"
|
||||
"memset(x, 0, sizeof(x));");
|
||||
" memset(x, 0, sizeof(x));\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" char x[10];\n"
|
||||
"memset(x, 0, sizeof x);");
|
||||
" memset(x, 0, sizeof x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(sizeof(int));\n"
|
||||
" memset(x, 0, sizeof(int));\n"
|
||||
"free(x);");
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(sizeof(int));\n"
|
||||
" memset(x, 0, sizeof(*x));\n"
|
||||
"free(x);");
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(sizeof(int));\n"
|
||||
" memset(x, 0, sizeof *x);\n"
|
||||
"free(x);");
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(sizeof(int));\n"
|
||||
" memset(x, 0, sizeof x);\n"
|
||||
"free(x);");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(sizeof(int));\n"
|
||||
" memset(x, 0, sizeof(x));\n"
|
||||
"free(x);");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(sizeof(int) * 10);\n"
|
||||
" memset(x, 0, sizeof(x) * 10);\n"
|
||||
"free(x);");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(sizeof(int) * 10);\n"
|
||||
" memset(x, 0, sizeof x * 10);\n"
|
||||
"free(x);");
|
||||
ASSERT_EQUALS("[test.cpp:2]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("[test.cpp:3]: (warning, inconclusive) Size of pointer 'x' used instead of size of its data.\n", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(sizeof(int) * 10);\n"
|
||||
" memset(x, 0, sizeof(*x) * 10);\n"
|
||||
"free(x);");
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(sizeof(int) * 10);\n"
|
||||
" memset(x, 0, sizeof *x * 10);\n"
|
||||
"free(x);");
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check(
|
||||
check("void f() {\n"
|
||||
" int *x = malloc(sizeof(int) * 10);\n"
|
||||
" memset(x, 0, sizeof(int) * 10);\n"
|
||||
"free(x);");
|
||||
" free(x);\n"
|
||||
"}");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
check(
|
||||
|
|
Loading…
Reference in New Issue