updated extracttests.py. fix syntax errors in test cases.
This commit is contained in:
parent
7ba9e37296
commit
d549770b5b
|
@ -2324,6 +2324,21 @@ const Variable *getLHSVariable(const Token *tok)
|
||||||
return getLHSVariableRecursive(tok->astOperand1());
|
return getLHSVariableRecursive(tok->astOperand1());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Token* findAllocFuncCallToken(const Token *expr, const Library &library)
|
||||||
|
{
|
||||||
|
if (!expr)
|
||||||
|
return nullptr;
|
||||||
|
if (Token::Match(expr, "[+-]")) {
|
||||||
|
const Token *tok1 = findAllocFuncCallToken(expr->astOperand1(), library);
|
||||||
|
return tok1 ? tok1 : findAllocFuncCallToken(expr->astOperand2(), library);
|
||||||
|
}
|
||||||
|
if (expr->isCast())
|
||||||
|
return findAllocFuncCallToken(expr->astOperand2() ? expr->astOperand2() : expr->astOperand1(), library);
|
||||||
|
if (Token::Match(expr->previous(), "%name% (") && library.getAllocFuncInfo(expr->astOperand1()))
|
||||||
|
return expr->astOperand1();
|
||||||
|
return (Token::simpleMatch(expr, "new") && expr->astOperand1()) ? expr : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
static bool nonLocal(const Variable* var, bool deref)
|
static bool nonLocal(const Variable* var, bool deref)
|
||||||
{
|
{
|
||||||
return !var || (!var->isLocal() && !var->isArgument()) || (deref && var->isArgument() && var->isPointer()) || var->isStatic() || var->isReference() || var->isExtern();
|
return !var || (!var->isLocal() && !var->isArgument()) || (deref && var->isArgument() && var->isPointer()) || var->isStatic() || var->isReference() || var->isExtern();
|
||||||
|
|
|
@ -281,6 +281,9 @@ const Variable *getLHSVariable(const Token *tok);
|
||||||
|
|
||||||
std::vector<const Variable*> getLHSVariables(const Token* tok);
|
std::vector<const Variable*> getLHSVariables(const Token* tok);
|
||||||
|
|
||||||
|
/** Find a allocation function call in expression, so result of expression is allocated memory/resource. */
|
||||||
|
const Token* findAllocFuncCallToken(const Token *expr, const Library &library);
|
||||||
|
|
||||||
bool isScopeBracket(const Token* tok);
|
bool isScopeBracket(const Token* tok);
|
||||||
|
|
||||||
bool isNullOperand(const Token *expr);
|
bool isNullOperand(const Token *expr);
|
||||||
|
|
|
@ -171,9 +171,12 @@ void CheckUninitVar::checkScope(const Scope* scope, const std::set<std::string>
|
||||||
if (arg.declarationId() && Token::Match(arg.typeStartToken(), "%type% * %name% [,)]")) {
|
if (arg.declarationId() && Token::Match(arg.typeStartToken(), "%type% * %name% [,)]")) {
|
||||||
// Treat the pointer as initialized until it is assigned by malloc
|
// Treat the pointer as initialized until it is assigned by malloc
|
||||||
for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) {
|
for (const Token *tok = scope->bodyStart; tok != scope->bodyEnd; tok = tok->next()) {
|
||||||
if (!Token::Match(tok, "[;{}] %varid% = %name% (", arg.declarationId()))
|
if (!Token::Match(tok, "[;{}] %varid% =", arg.declarationId()))
|
||||||
continue;
|
continue;
|
||||||
const Library::AllocFunc *allocFunc = mSettings->library.getAllocFuncInfo(tok->tokAt(3));
|
const Token *allocFuncCallToken = findAllocFuncCallToken(tok->tokAt(2)->astOperand2(), mSettings->library);
|
||||||
|
if (!allocFuncCallToken)
|
||||||
|
continue;
|
||||||
|
const Library::AllocFunc *allocFunc = mSettings->library.getAllocFuncInfo(allocFuncCallToken);
|
||||||
if (!allocFunc || allocFunc->initData)
|
if (!allocFunc || allocFunc->initData)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -938,11 +938,14 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
|
||||||
}
|
}
|
||||||
// Consider allocating memory separately because allocating/freeing alone does not constitute using the variable
|
// Consider allocating memory separately because allocating/freeing alone does not constitute using the variable
|
||||||
else if (var && var->mType == Variables::pointer &&
|
else if (var && var->mType == Variables::pointer &&
|
||||||
Token::Match(start, "%name% = new|malloc|calloc|kmalloc|kzalloc|kcalloc|strdup|strndup|vmalloc|g_new0|g_try_new|g_new|g_malloc|g_malloc0|g_try_malloc|g_try_malloc0|g_strdup|g_strndup|g_strdup_printf")) {
|
Token::Match(start, "%name% =") &&
|
||||||
|
findAllocFuncCallToken(start->next()->astOperand2(), mSettings->library)) {
|
||||||
bool allocate = true;
|
bool allocate = true;
|
||||||
|
|
||||||
if (start->strAt(2) == "new") {
|
const Token *allocFuncCallToken = findAllocFuncCallToken(start->next()->astOperand2(), mSettings->library);
|
||||||
const Token *type = start->tokAt(3);
|
|
||||||
|
if (allocFuncCallToken->str() == "new") {
|
||||||
|
const Token *type = allocFuncCallToken->next();
|
||||||
|
|
||||||
// skip nothrow
|
// skip nothrow
|
||||||
if (mTokenizer->isCPP() && (Token::simpleMatch(type, "( nothrow )") ||
|
if (mTokenizer->isCPP() && (Token::simpleMatch(type, "( nothrow )") ||
|
||||||
|
|
|
@ -1013,6 +1013,7 @@ private:
|
||||||
|
|
||||||
void array_index_30() {
|
void array_index_30() {
|
||||||
// ticket #2086 - unknown type
|
// ticket #2086 - unknown type
|
||||||
|
// extracttests.start: typedef unsigned char UINT8;
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" UINT8 x[2];\n"
|
" UINT8 x[2];\n"
|
||||||
" x[5] = 0;\n"
|
" x[5] = 0;\n"
|
||||||
|
@ -1245,7 +1246,7 @@ private:
|
||||||
|
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char *p; p = malloc(10);\n"
|
" char *p; p = (char *)malloc(10);\n"
|
||||||
" p[10] = 7;\n"
|
" p[10] = 7;\n"
|
||||||
" free(p);\n"
|
" free(p);\n"
|
||||||
"}");
|
"}");
|
||||||
|
@ -1253,7 +1254,7 @@ private:
|
||||||
|
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char *p; p = malloc(10);\n"
|
" char *p; p = (char *)malloc(10);\n"
|
||||||
" p[0] = 0;\n"
|
" p[0] = 0;\n"
|
||||||
" p[9] = 9;\n"
|
" p[9] = 9;\n"
|
||||||
" free(p);\n"
|
" free(p);\n"
|
||||||
|
@ -1880,6 +1881,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void array_index_for_andand_oror() { // #3907 - using && or ||
|
void array_index_for_andand_oror() { // #3907 - using && or ||
|
||||||
|
// extracttests.start: volatile int y;
|
||||||
|
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" char data[2];\n"
|
" char data[2];\n"
|
||||||
" int x;\n"
|
" int x;\n"
|
||||||
|
@ -1930,10 +1933,11 @@ private:
|
||||||
"}", true);
|
"}", true);
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: int maybe();
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" int a[2];\n"
|
" int a[2];\n"
|
||||||
" for (int i = 0; i < 2; ++i) {\n"
|
" for (int i = 0; i < 2; ++i) {\n"
|
||||||
" if (somecondition) {\n"
|
" if (maybe()) {\n"
|
||||||
" continue;\n"
|
" continue;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" a[i - 1] = 0;\n"
|
" a[i - 1] = 0;\n"
|
||||||
|
@ -1967,9 +1971,10 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
// Ticket #3893 - start value out of bounds
|
// Ticket #3893 - start value out of bounds
|
||||||
|
// extracttests.start: int maybe(); int dostuff();
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" int a[10];\n"
|
" int a[10];\n"
|
||||||
" for (int i = 10; somecondition; dosomething) {\n"
|
" for (int i = 10; maybe(); dostuff()) {\n"
|
||||||
" a[i] = 0;\n"
|
" a[i] = 0;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}");
|
"}");
|
||||||
|
@ -2748,21 +2753,21 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (warning) The array 'a' is too small, the function 'f' expects a bigger one.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (warning) The array 'a' is too small, the function 'f' expects a bigger one.\n", errout.str());
|
||||||
|
|
||||||
check("void f(float a[10][20]);\n"
|
check("void f(float a[10][3]);\n"
|
||||||
"void g() {\n"
|
"void g() {\n"
|
||||||
" float a[2][3];\n"
|
" float a[2][3];\n"
|
||||||
" f(a);\n"
|
" f(a);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (warning) The array 'a' is too small, the function 'f' expects a bigger one.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (warning) The array 'a' is too small, the function 'f' expects a bigger one.\n", errout.str());
|
||||||
|
|
||||||
check("void f(char a[20]);\n"
|
check("void f(int a[20]);\n"
|
||||||
"void g() {\n"
|
"void g() {\n"
|
||||||
" int a[2];\n"
|
" int a[2];\n"
|
||||||
" f(a);\n"
|
" f(a);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (warning) The array 'a' is too small, the function 'f' expects a bigger one.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (warning) The array 'a' is too small, the function 'f' expects a bigger one.\n", errout.str());
|
||||||
|
|
||||||
check("void f(char a[20]);\n"
|
check("void f(int a[20]);\n"
|
||||||
"void g() {\n"
|
"void g() {\n"
|
||||||
" int a[5];\n"
|
" int a[5];\n"
|
||||||
" f(a);\n"
|
" f(a);\n"
|
||||||
|
@ -2791,7 +2796,7 @@ private:
|
||||||
|
|
||||||
void possible_buffer_overrun_1() { // #3035
|
void possible_buffer_overrun_1() { // #3035
|
||||||
check("void foo() {\n"
|
check("void foo() {\n"
|
||||||
" char * data = alloca(50);\n"
|
" char * data = (char *)alloca(50);\n"
|
||||||
" char src[100];\n"
|
" char src[100];\n"
|
||||||
" memset(src, 'C', 99);\n"
|
" memset(src, 'C', 99);\n"
|
||||||
" src[99] = '\\0';\n"
|
" src[99] = '\\0';\n"
|
||||||
|
@ -2800,7 +2805,7 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:6]: (warning) Possible buffer overflow if strlen(src) is larger than sizeof(data)-strlen(data).\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:6]: (warning) Possible buffer overflow if strlen(src) is larger than sizeof(data)-strlen(data).\n", errout.str());
|
||||||
|
|
||||||
check("void foo() {\n"
|
check("void foo() {\n"
|
||||||
" char * data = alloca(100);\n"
|
" char * data = (char *)alloca(100);\n"
|
||||||
" char src[100];\n"
|
" char src[100];\n"
|
||||||
" memset(src, 'C', 99);\n"
|
" memset(src, 'C', 99);\n"
|
||||||
" src[99] = '\\0';\n"
|
" src[99] = '\\0';\n"
|
||||||
|
@ -2809,19 +2814,19 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check("void foo(char src[100]) {\n"
|
check("void foo(char src[100]) {\n"
|
||||||
" char * data = alloca(50);\n"
|
" char * data = (char *)alloca(50);\n"
|
||||||
" strcat(data, src);\n"
|
" strcat(data, src);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Possible buffer overflow if strlen(src) is larger than sizeof(data)-strlen(data).\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (warning) Possible buffer overflow if strlen(src) is larger than sizeof(data)-strlen(data).\n", errout.str());
|
||||||
|
|
||||||
check("void foo(char src[100]) {\n"
|
check("void foo(char src[100]) {\n"
|
||||||
" char * data = alloca(100);\n"
|
" char * data = (char *)alloca(100);\n"
|
||||||
" strcat(data, src);\n"
|
" strcat(data, src);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check("void foo() {\n"
|
check("void foo() {\n"
|
||||||
" char * data = alloca(50);\n"
|
" char * data = (char *)alloca(50);\n"
|
||||||
" char src[100];\n"
|
" char src[100];\n"
|
||||||
" memset(src, 'C', 99);\n"
|
" memset(src, 'C', 99);\n"
|
||||||
" src[99] = '\\0';\n"
|
" src[99] = '\\0';\n"
|
||||||
|
@ -2830,7 +2835,7 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:6]: (warning) Possible buffer overflow if strlen(src) is larger than or equal to sizeof(data).\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:6]: (warning) Possible buffer overflow if strlen(src) is larger than or equal to sizeof(data).\n", errout.str());
|
||||||
|
|
||||||
check("void foo() {\n"
|
check("void foo() {\n"
|
||||||
" char * data = alloca(100);\n"
|
" char * data = (char *)alloca(100);\n"
|
||||||
" char src[100];\n"
|
" char src[100];\n"
|
||||||
" memset(src, 'C', 99);\n"
|
" memset(src, 'C', 99);\n"
|
||||||
" src[99] = '\\0';\n"
|
" src[99] = '\\0';\n"
|
||||||
|
@ -2839,13 +2844,13 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check("void foo(char src[100]) {\n"
|
check("void foo(char src[100]) {\n"
|
||||||
" char * data = alloca(50);\n"
|
" char * data = (char *)alloca(50);\n"
|
||||||
" strcpy(data, src);\n"
|
" strcpy(data, src);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (warning) Possible buffer overflow if strlen(src) is larger than or equal to sizeof(data).\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (warning) Possible buffer overflow if strlen(src) is larger than or equal to sizeof(data).\n", errout.str());
|
||||||
|
|
||||||
check("void foo(char src[100]) {\n"
|
check("void foo(char src[100]) {\n"
|
||||||
" char * data = alloca(100);\n"
|
" char * data = (char *)alloca(100);\n"
|
||||||
" strcpy(data, src);\n"
|
" strcpy(data, src);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
@ -2905,13 +2910,15 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void pointer_out_of_bounds_1() {
|
void pointer_out_of_bounds_1() {
|
||||||
|
// extracttests.start: void dostuff(char *);
|
||||||
|
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" char a[10];\n"
|
" char a[10];\n"
|
||||||
" char *p = a + 100;\n"
|
" char *p = a + 100;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (portability) Undefined behaviour, pointer arithmetic 'a+100' is out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (portability) Undefined behaviour, pointer arithmetic 'a+100' is out of bounds.\n", errout.str());
|
||||||
|
|
||||||
check("void f() {\n"
|
check("char *f() {\n"
|
||||||
" char a[10];\n"
|
" char a[10];\n"
|
||||||
" return a + 100;\n"
|
" return a + 100;\n"
|
||||||
"}");
|
"}");
|
||||||
|
@ -2983,7 +2990,7 @@ private:
|
||||||
void pointer_out_of_bounds_3() {
|
void pointer_out_of_bounds_3() {
|
||||||
check("struct S { int a[10]; };\n"
|
check("struct S { int a[10]; };\n"
|
||||||
"void f(struct S *s) {\n"
|
"void f(struct S *s) {\n"
|
||||||
" char *p = s->a + 100;\n"
|
" int *p = s->a + 100;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (portability) Undefined behaviour, pointer arithmetic 's->a+100' is out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (portability) Undefined behaviour, pointer arithmetic 's->a+100' is out of bounds.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
@ -3012,7 +3019,9 @@ private:
|
||||||
|
|
||||||
|
|
||||||
void pointer_out_of_bounds_sub() {
|
void pointer_out_of_bounds_sub() {
|
||||||
check("void f() {\n"
|
// extracttests.start: void dostuff(char *);
|
||||||
|
|
||||||
|
check("char *f() {\n"
|
||||||
" char x[10];\n"
|
" char x[10];\n"
|
||||||
" return x-1;\n"
|
" return x-1;\n"
|
||||||
"}");
|
"}");
|
||||||
|
@ -3129,7 +3138,7 @@ private:
|
||||||
// ticket #1670 - false negative when using return
|
// ticket #1670 - false negative when using return
|
||||||
check("char f()\n"
|
check("char f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char *s; s = new int[10];\n"
|
" int *s; s = new int[10];\n"
|
||||||
" return s[10];\n"
|
" return s[10];\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 's[10]' accessed at index 10, which is out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Array 's[10]' accessed at index 10, which is out of bounds.\n", errout.str());
|
||||||
|
@ -3177,9 +3186,9 @@ private:
|
||||||
|
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" enum E { };\n"
|
" enum E { ZERO };\n"
|
||||||
" E *e; e = new E[10];\n"
|
" E *e; e = new E[10];\n"
|
||||||
" e[10] = 0;\n"
|
" e[10] = ZERO;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Array 'e[10]' accessed at index 10, which is out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Array 'e[10]' accessed at index 10, which is out of bounds.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
@ -3188,23 +3197,23 @@ private:
|
||||||
void alloc_malloc() {
|
void alloc_malloc() {
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char *s; s = malloc(10);\n"
|
" char *s; s = (char *)malloc(10);\n"
|
||||||
" s[10] = 0;\n"
|
" s[10] = 0;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 's[10]' accessed at index 10, which is out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Array 's[10]' accessed at index 10, which is out of bounds.\n", errout.str());
|
||||||
|
|
||||||
// ticket #842
|
// ticket #842
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" int *tab4 = malloc(20 * sizeof(int));\n"
|
" int *tab4 = (int *)malloc(20 * sizeof(int));\n"
|
||||||
" tab4[20] = 0;\n"
|
" tab4[20] = 0;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Array 'tab4[20]' accessed at index 20, which is out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Array 'tab4[20]' accessed at index 20, which is out of bounds.\n", errout.str());
|
||||||
|
|
||||||
// ticket #1478
|
// ticket #1478
|
||||||
check("void foo() {\n"
|
check("void foo() {\n"
|
||||||
" char *p = malloc(10);\n"
|
" char *p = (char *)malloc(10);\n"
|
||||||
" free(p);\n"
|
" free(p);\n"
|
||||||
" p = malloc(10);\n"
|
" p = (char *)malloc(10);\n"
|
||||||
" p[10] = 0;\n"
|
" p[10] = 0;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Array 'p[10]' accessed at index 10, which is out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Array 'p[10]' accessed at index 10, which is out of bounds.\n", errout.str());
|
||||||
|
@ -3212,7 +3221,7 @@ private:
|
||||||
// ticket #1134
|
// ticket #1134
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" int *x, i;\n"
|
" int *x, i;\n"
|
||||||
" x = malloc(10 * sizeof(int));\n"
|
" x = (int *)malloc(10 * sizeof(int));\n"
|
||||||
" x[10] = 0;\n"
|
" x[10] = 0;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'x[10]' accessed at index 10, which is out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'x[10]' accessed at index 10, which is out of bounds.\n", errout.str());
|
||||||
|
@ -3238,22 +3247,22 @@ private:
|
||||||
|
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" enum E { Size = 20 };\n"
|
" enum E { Size = 20 };\n"
|
||||||
" E *tab4 = malloc(Size * 4);\n"
|
" E *tab4 = (E *)malloc(Size * 4);\n"
|
||||||
" tab4[Size] = 0;\n"
|
" tab4[Size] = Size;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'tab4[20]' accessed at index 20, which is out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'tab4[20]' accessed at index 20, which is out of bounds.\n", errout.str());
|
||||||
|
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" enum E { Size = 20 };\n"
|
" enum E { Size = 20 };\n"
|
||||||
" E *tab4 = malloc(4 * Size);\n"
|
" E *tab4 = (E *)malloc(4 * Size);\n"
|
||||||
" tab4[Size] = 0;\n"
|
" tab4[Size] = Size;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'tab4[20]' accessed at index 20, which is out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'tab4[20]' accessed at index 20, which is out of bounds.\n", errout.str());
|
||||||
|
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" enum E { };\n"
|
" enum E { ZERO };\n"
|
||||||
" E *tab4 = malloc(20 * sizeof(E));\n"
|
" E *tab4 = (E *)malloc(20 * sizeof(E));\n"
|
||||||
" tab4[20] = 0;\n"
|
" tab4[20] = ZERO;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'tab4[20]' accessed at index 20, which is out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Array 'tab4[20]' accessed at index 20, which is out of bounds.\n", errout.str());
|
||||||
|
|
||||||
|
@ -3301,7 +3310,7 @@ private:
|
||||||
void alloc_alloca() {
|
void alloc_alloca() {
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char *s = alloca(10);\n"
|
" char *s = (char *)alloca(10);\n"
|
||||||
" s[10] = 0;\n"
|
" s[10] = 0;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Array 's[10]' accessed at index 10, which is out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Array 's[10]' accessed at index 10, which is out of bounds.\n", errout.str());
|
||||||
|
@ -3378,6 +3387,9 @@ private:
|
||||||
ASSERT_EQUALS(26, CheckBufferOverrun::countSprintfLength("str%-6s%08ld%08ld", multipleParams));
|
ASSERT_EQUALS(26, CheckBufferOverrun::countSprintfLength("str%-6s%08ld%08ld", multipleParams));
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
// extracttests.disable
|
||||||
|
|
||||||
void minsize_argvalue() {
|
void minsize_argvalue() {
|
||||||
Settings settings;
|
Settings settings;
|
||||||
const char xmldata[] = "<?xml version=\"1.0\"?>\n"
|
const char xmldata[] = "<?xml version=\"1.0\"?>\n"
|
||||||
|
@ -3717,6 +3729,8 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Buffer is accessed out of bounds: c\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Buffer is accessed out of bounds: c\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// extracttests.enable
|
||||||
|
|
||||||
void unknownType() {
|
void unknownType() {
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -3770,7 +3784,7 @@ private:
|
||||||
" char baz[100];\n"
|
" char baz[100];\n"
|
||||||
" strncpy(baz, bar, 100);\n"
|
" strncpy(baz, bar, 100);\n"
|
||||||
" bar[99] = 0;\n"
|
" bar[99] = 0;\n"
|
||||||
" return baz;\n"
|
" return strdup(baz);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (warning, inconclusive) The buffer 'baz' may not be null-terminated after the call to strncpy().\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (warning, inconclusive) The buffer 'baz' may not be null-terminated after the call to strncpy().\n", errout.str());
|
||||||
}
|
}
|
||||||
|
@ -4095,20 +4109,20 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check("void f(char *a) {\n"
|
check("void f(char *a) {\n"
|
||||||
" char *b = malloc(strlen(a));\n"
|
" char *b = (char *)malloc(strlen(a));\n"
|
||||||
" b = realloc(b, 10000);\n"
|
" b = realloc(b, 10000);\n"
|
||||||
" strcpy(b, a);\n"
|
" strcpy(b, a);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check("void f(char *a) {\n"
|
check("void f(char *a) {\n"
|
||||||
" char *b = malloc(strlen(a));\n"
|
" char *b = (char *)malloc(strlen(a));\n"
|
||||||
" strcpy(b, a);\n"
|
" strcpy(b, a);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Buffer is accessed out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Buffer is accessed out of bounds.\n", errout.str());
|
||||||
|
|
||||||
check("void f(char *a) {\n"
|
check("void f(char *a) {\n"
|
||||||
" char *b = malloc(strlen(a));\n"
|
" char *b = (char *)malloc(strlen(a));\n"
|
||||||
" {\n"
|
" {\n"
|
||||||
" strcpy(b, a);\n"
|
" strcpy(b, a);\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
|
@ -4116,25 +4130,25 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer is accessed out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Buffer is accessed out of bounds.\n", errout.str());
|
||||||
|
|
||||||
check("void f(char *a) {\n"
|
check("void f(char *a) {\n"
|
||||||
" char *b = malloc(strlen(a) + 1);\n"
|
" char *b = (char *)malloc(strlen(a) + 1);\n"
|
||||||
" strcpy(b, a);\n"
|
" strcpy(b, a);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check("void f(char *a, char *c) {\n"
|
check("void f(char *a, char *c) {\n"
|
||||||
" char *b = realloc(c, strlen(a));\n"
|
" char *b = (char *)realloc(c, strlen(a));\n"
|
||||||
" strcpy(b, a);\n"
|
" strcpy(b, a);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Buffer is accessed out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Buffer is accessed out of bounds.\n", errout.str());
|
||||||
|
|
||||||
check("void f(char *a, char *c) {\n"
|
check("void f(char *a, char *c) {\n"
|
||||||
" char *b = realloc(c, strlen(a) + 1);\n"
|
" char *b = (char *)realloc(c, strlen(a) + 1);\n"
|
||||||
" strcpy(b, a);\n"
|
" strcpy(b, a);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check("void f(char *a) {\n"
|
check("void f(char *a) {\n"
|
||||||
" char *b = malloc(strlen(a));\n"
|
" char *b = (char *)malloc(strlen(a));\n"
|
||||||
" strcpy(b, a);\n"
|
" strcpy(b, a);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Buffer is accessed out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Buffer is accessed out of bounds.\n", errout.str());
|
||||||
|
@ -4144,7 +4158,7 @@ private:
|
||||||
check("class A {\n"
|
check("class A {\n"
|
||||||
"private:\n"
|
"private:\n"
|
||||||
" struct X { char buf[10]; };\n"
|
" struct X { char buf[10]; };\n"
|
||||||
"}\n"
|
"};\n"
|
||||||
"\n"
|
"\n"
|
||||||
"void f()\n"
|
"void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -4156,7 +4170,7 @@ private:
|
||||||
check("class A {\n"
|
check("class A {\n"
|
||||||
"public:\n"
|
"public:\n"
|
||||||
" struct X { char buf[10]; };\n"
|
" struct X { char buf[10]; };\n"
|
||||||
"}\n"
|
"};\n"
|
||||||
"\n"
|
"\n"
|
||||||
"void f()\n"
|
"void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -4173,6 +4187,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void arrayIndexThenCheck() {
|
void arrayIndexThenCheck() {
|
||||||
|
// extracttests.start: volatile int y;
|
||||||
|
|
||||||
check("void f(const char s[]) {\n"
|
check("void f(const char s[]) {\n"
|
||||||
" if (s[i] == 'x' && i < y) {\n"
|
" if (s[i] == 'x' && i < y) {\n"
|
||||||
" }"
|
" }"
|
||||||
|
@ -4203,12 +4219,14 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (style) Array index 'i' is used before limits check.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (style) Array index 'i' is used before limits check.\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: int elen;
|
||||||
check("void f(char* e, int y) {\n"
|
check("void f(char* e, int y) {\n"
|
||||||
" if (e[y] == '/' && elen > y + 1 && e[y + 1] == '?') {\n"
|
" if (e[y] == '/' && elen > y + 1 && e[y + 1] == '?') {\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: int foo(int); int func(int);
|
||||||
check("void f(const int a[], unsigned i) {\n"
|
check("void f(const int a[], unsigned i) {\n"
|
||||||
" if(a[i] < func(i) && i <= 42) {\n"
|
" if(a[i] < func(i) && i <= 42) {\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
|
@ -4232,6 +4250,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: extern int buf[];
|
||||||
check("void f(int i) {\n" // ?:
|
check("void f(int i) {\n" // ?:
|
||||||
" if ((i < 10 ? buf[i] : 1) && (i < 5 ? buf[i] : 5)){}\n"
|
" if ((i < 10 ? buf[i] : 1) && (i < 5 ? buf[i] : 5)){}\n"
|
||||||
"}");
|
"}");
|
||||||
|
@ -4262,15 +4281,7 @@ private:
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int *a;\n"
|
" int *a;\n"
|
||||||
" a = new int[-1];\n"
|
" a = (int *)malloc( -10 );\n"
|
||||||
" delete [] a;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Memory allocation size is negative.\n", errout.str());
|
|
||||||
|
|
||||||
check("void f()\n"
|
|
||||||
"{\n"
|
|
||||||
" int *a;\n"
|
|
||||||
" a = malloc( -10 );\n"
|
|
||||||
" free(a);\n"
|
" free(a);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Memory allocation size is negative.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Memory allocation size is negative.\n", errout.str());
|
||||||
|
@ -4278,7 +4289,7 @@ private:
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int *a;\n"
|
" int *a;\n"
|
||||||
" a = malloc( -10);\n"
|
" a = (int *)malloc( -10);\n"
|
||||||
" free(a);\n"
|
" free(a);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Memory allocation size is negative.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Memory allocation size is negative.\n", errout.str());
|
||||||
|
@ -4286,7 +4297,7 @@ private:
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int *a;\n"
|
" int *a;\n"
|
||||||
" a = alloca( -10 );\n"
|
" a = (int *)alloca( -10 );\n"
|
||||||
" free(a);\n"
|
" free(a);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Memory allocation size is negative.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Memory allocation size is negative.\n", errout.str());
|
||||||
|
@ -4310,7 +4321,7 @@ private:
|
||||||
void pointerAddition1() {
|
void pointerAddition1() {
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" char arr[10];\n"
|
" char arr[10];\n"
|
||||||
" p = arr + 20;\n"
|
" char *p = arr + 20;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (portability) Undefined behaviour, pointer arithmetic 'arr+20' is out of bounds.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (portability) Undefined behaviour, pointer arithmetic 'arr+20' is out of bounds.\n", errout.str());
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,7 +191,8 @@ private:
|
||||||
|
|
||||||
|
|
||||||
void nullpointerAfterLoop() {
|
void nullpointerAfterLoop() {
|
||||||
check("int foo(const Token *tok)\n"
|
// extracttests.start: struct Token { const Token *next() const; std::string str() const; };
|
||||||
|
check("void foo(const Token *tok)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" while (tok);\n"
|
" while (tok);\n"
|
||||||
" tok = tok->next();\n"
|
" tok = tok->next();\n"
|
||||||
|
@ -363,6 +364,8 @@ private:
|
||||||
// This is checked by this function:
|
// This is checked by this function:
|
||||||
// CheckOther::nullPointerStructByDeRefAndChec
|
// CheckOther::nullPointerStructByDeRefAndChec
|
||||||
void structDerefAndCheck() {
|
void structDerefAndCheck() {
|
||||||
|
// extracttests.start: struct ABC { int a; int b; int x; };
|
||||||
|
|
||||||
// errors..
|
// errors..
|
||||||
check("void foo(struct ABC *abc)\n"
|
check("void foo(struct ABC *abc)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -622,6 +625,8 @@ private:
|
||||||
|
|
||||||
// Dereferencing a pointer and then checking if it is null
|
// Dereferencing a pointer and then checking if it is null
|
||||||
void pointerDerefAndCheck() {
|
void pointerDerefAndCheck() {
|
||||||
|
// extracttests.start: void bar(int);
|
||||||
|
|
||||||
// errors..
|
// errors..
|
||||||
check("void foo(int *p)\n"
|
check("void foo(int *p)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -992,14 +997,14 @@ private:
|
||||||
"", errout.str());
|
"", errout.str());
|
||||||
|
|
||||||
check("static void foo() {\n"
|
check("static void foo() {\n"
|
||||||
" int &r = *0;\n"
|
" int &r = *(int*)0;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error) Null pointer dereference\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (error) Null pointer dereference: (int*)0\n", errout.str());
|
||||||
|
|
||||||
check("static void foo(int x) {\n"
|
check("static void foo(int x) {\n"
|
||||||
" int y = 5 + *0;\n"
|
" int y = 5 + *(int*)0;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error) Null pointer dereference\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (error) Null pointer dereference: (int*)0\n", errout.str());
|
||||||
|
|
||||||
{
|
{
|
||||||
const char code[] = "static void foo() {\n"
|
const char code[] = "static void foo() {\n"
|
||||||
|
@ -1012,9 +1017,9 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
check("static void foo() {\n"
|
check("static void foo() {\n"
|
||||||
" std::cout << *0;"
|
" std::cout << *(int*)0;"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error) Null pointer dereference\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (error) Null pointer dereference: (int*)0\n", errout.str());
|
||||||
|
|
||||||
check("void f()\n"
|
check("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -1027,9 +1032,9 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:7]: (error) Null pointer dereference: c\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:7]: (error) Null pointer dereference: c\n", errout.str());
|
||||||
|
|
||||||
check("static void foo() {\n"
|
check("static void foo() {\n"
|
||||||
" if (3 > *0);\n"
|
" if (3 > *(int*)0);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error) Null pointer dereference\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (error) Null pointer dereference: (int*)0\n", errout.str());
|
||||||
|
|
||||||
// no false positive..
|
// no false positive..
|
||||||
check("static void foo()\n"
|
check("static void foo()\n"
|
||||||
|
@ -1218,12 +1223,13 @@ private:
|
||||||
"", errout.str());
|
"", errout.str());
|
||||||
|
|
||||||
// #2231 - error if assignment in loop is not used
|
// #2231 - error if assignment in loop is not used
|
||||||
|
// extracttests.start: int y[20];
|
||||||
check("void f() {\n"
|
check("void f() {\n"
|
||||||
" char *p = 0;\n"
|
" char *p = 0;\n"
|
||||||
"\n"
|
"\n"
|
||||||
" for (int x = 0; x < 3; ++x) {\n"
|
" for (int x = 0; x < 3; ++x) {\n"
|
||||||
" if (y[x] == 0) {\n"
|
" if (y[x] == 0) {\n"
|
||||||
" p = malloc(10);\n"
|
" p = (char *)malloc(10);\n"
|
||||||
" break;\n"
|
" break;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
|
@ -1252,6 +1258,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void nullpointer10() {
|
void nullpointer10() {
|
||||||
|
// extracttests.start: struct my_type { int x; };
|
||||||
check("void foo()\n"
|
check("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" struct my_type* p = 0;\n"
|
" struct my_type* p = 0;\n"
|
||||||
|
@ -1261,6 +1268,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void nullpointer11() { // ticket #2812
|
void nullpointer11() { // ticket #2812
|
||||||
|
// extracttests.start: struct my_type { int x; };
|
||||||
|
|
||||||
check("int foo()\n"
|
check("int foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" struct my_type* p;\n"
|
" struct my_type* p;\n"
|
||||||
|
@ -2184,7 +2193,7 @@ private:
|
||||||
" const Token* next() const;\n"
|
" const Token* next() const;\n"
|
||||||
" int varId() const;\n"
|
" int varId() const;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"int f(const Token *first, const Token* second) const {\n"
|
"int f(const Token *first, const Token* second) {\n"
|
||||||
" first = first->nextArgument();\n"
|
" first = first->nextArgument();\n"
|
||||||
" if (first)\n"
|
" if (first)\n"
|
||||||
" first = first->next();\n"
|
" first = first->next();\n"
|
||||||
|
@ -2203,8 +2212,9 @@ private:
|
||||||
" const Token* nextArgument() const;\n"
|
" const Token* nextArgument() const;\n"
|
||||||
" const Token* next() const;\n"
|
" const Token* next() const;\n"
|
||||||
" int varId() const;\n"
|
" int varId() const;\n"
|
||||||
|
" void str() const;"
|
||||||
"};\n"
|
"};\n"
|
||||||
"int f(const Token *first) const {\n"
|
"void f(const Token *first) {\n"
|
||||||
" first = first->nextArgument();\n"
|
" first = first->nextArgument();\n"
|
||||||
" if (first)\n"
|
" if (first)\n"
|
||||||
" first = first->next();\n"
|
" first = first->next();\n"
|
||||||
|
@ -2246,6 +2256,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void nullpointerSwitch() { // #2626
|
void nullpointerSwitch() { // #2626
|
||||||
|
// extracttests.start: char *do_something();
|
||||||
check("char *f(int x) {\n"
|
check("char *f(int x) {\n"
|
||||||
" char *p = do_something();\n"
|
" char *p = do_something();\n"
|
||||||
" switch (x) {\n"
|
" switch (x) {\n"
|
||||||
|
@ -2667,7 +2678,7 @@ private:
|
||||||
|
|
||||||
// Test CheckNullPointer::nullConstantDereference
|
// Test CheckNullPointer::nullConstantDereference
|
||||||
void nullConstantDereference() {
|
void nullConstantDereference() {
|
||||||
check("void f() {\n"
|
check("int f() {\n"
|
||||||
" int* p = 0;\n"
|
" int* p = 0;\n"
|
||||||
" return p[4];\n"
|
" return p[4];\n"
|
||||||
"}");
|
"}");
|
||||||
|
@ -2836,9 +2847,10 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void nullpointer_in_return() {
|
void nullpointer_in_return() {
|
||||||
|
// extracttests.start: int maybe(); int *g();
|
||||||
check("int foo() {\n"
|
check("int foo() {\n"
|
||||||
" int* iVal = 0;\n"
|
" int* iVal = 0;\n"
|
||||||
" if(g()) iVal = g();\n"
|
" if(maybe()) iVal = g();\n"
|
||||||
" return iVal[0];\n"
|
" return iVal[0];\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (warning) Possible null pointer dereference: iVal\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (warning) Possible null pointer dereference: iVal\n", errout.str());
|
||||||
|
@ -3130,6 +3142,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void nullpointerSmartPointer() {
|
void nullpointerSmartPointer() {
|
||||||
|
// extracttests.start: void dostuff(int);
|
||||||
|
|
||||||
check("struct Fred { int x; };\n"
|
check("struct Fred { int x; };\n"
|
||||||
"void f(std::shared_ptr<Fred> p) {\n"
|
"void f(std::shared_ptr<Fred> p) {\n"
|
||||||
" if (p) {}\n"
|
" if (p) {}\n"
|
||||||
|
@ -3190,7 +3204,7 @@ private:
|
||||||
|
|
||||||
check("struct Fred { int x; };\n"
|
check("struct Fred { int x; };\n"
|
||||||
"void f(std::shared_ptr<Fred> p) {\n"
|
"void f(std::shared_ptr<Fred> p) {\n"
|
||||||
" p.release();\n"
|
" p.reset();\n"
|
||||||
" dostuff(p->x);\n"
|
" dostuff(p->x);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference: p\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Null pointer dereference: p\n", errout.str());
|
||||||
|
@ -3547,7 +3561,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
check("void foo(int *p = 0) {\n"
|
check("void foo(int x, int *p = 0) {\n"
|
||||||
" int var1 = x ? *p : 5;\n"
|
" int var1 = x ? *p : 5;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (warning) Possible null pointer dereference if the default parameter value is used: p\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (warning) Possible null pointer dereference if the default parameter value is used: p\n", errout.str());
|
||||||
|
@ -3582,7 +3596,7 @@ private:
|
||||||
|
|
||||||
void subtract() {
|
void subtract() {
|
||||||
check("void foo(char *s) {\n"
|
check("void foo(char *s) {\n"
|
||||||
" p = s - 20;\n"
|
" char *p = s - 20;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
"void bar() { foo(0); }");
|
"void bar() { foo(0); }");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error) Overflow in pointer arithmetic, NULL pointer is subtracted.\n",
|
ASSERT_EQUALS("[test.cpp:2]: (error) Overflow in pointer arithmetic, NULL pointer is subtracted.\n",
|
||||||
|
@ -3590,7 +3604,7 @@ private:
|
||||||
|
|
||||||
check("void foo(char *s) {\n"
|
check("void foo(char *s) {\n"
|
||||||
" if (!s) {}\n"
|
" if (!s) {}\n"
|
||||||
" p = s - 20;\n"
|
" char *p = s - 20;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Either the condition '!s' is redundant or there is overflow in pointer subtraction.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2] -> [test.cpp:3]: (warning) Either the condition '!s' is redundant or there is overflow in pointer subtraction.\n", errout.str());
|
||||||
|
|
||||||
|
|
|
@ -113,6 +113,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninitvar1() {
|
void uninitvar1() {
|
||||||
|
// extracttests.start: int b; int c;
|
||||||
|
|
||||||
// Ticket #2207 - False negative
|
// Ticket #2207 - False negative
|
||||||
checkUninitVar("void foo() {\n"
|
checkUninitVar("void foo() {\n"
|
||||||
" int a;\n"
|
" int a;\n"
|
||||||
|
@ -127,11 +129,13 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
|
||||||
|
|
||||||
// Ticket #6455 - some compilers allow const variables to be uninitialized
|
// Ticket #6455 - some compilers allow const variables to be uninitialized
|
||||||
|
// extracttests.disable
|
||||||
checkUninitVar("void foo() {\n"
|
checkUninitVar("void foo() {\n"
|
||||||
" const int a;\n"
|
" const int a;\n"
|
||||||
" b = c - a;\n"
|
" b = c - a;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
|
||||||
|
// extracttests.enable
|
||||||
|
|
||||||
checkUninitVar("void foo() {\n"
|
checkUninitVar("void foo() {\n"
|
||||||
" int *p;\n"
|
" int *p;\n"
|
||||||
|
@ -153,6 +157,7 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
// dereferencing uninitialized pointer..
|
// dereferencing uninitialized pointer..
|
||||||
|
// extracttests.start: struct Foo { void abcd(); };
|
||||||
checkUninitVar("static void foo()\n"
|
checkUninitVar("static void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" Foo *p;\n"
|
" Foo *p;\n"
|
||||||
|
@ -160,6 +165,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: template<class T> struct Foo { void abcd(); };
|
||||||
checkUninitVar("static void foo()\n"
|
checkUninitVar("static void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" Foo<int> *p;\n"
|
" Foo<int> *p;\n"
|
||||||
|
@ -167,6 +173,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: p\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: struct Foo { void* a; };
|
||||||
checkUninitVar("void f(Foo *p)\n"
|
checkUninitVar("void f(Foo *p)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int a;\n"
|
" int a;\n"
|
||||||
|
@ -257,6 +264,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: void bar(int);
|
||||||
checkUninitVar("void f()\n"
|
checkUninitVar("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int a;\n"
|
" int a;\n"
|
||||||
|
@ -285,7 +293,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: i\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("static int foo(int x)\n"
|
checkUninitVar("static void foo(int x)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int i;\n"
|
" int i;\n"
|
||||||
" if (x)\n"
|
" if (x)\n"
|
||||||
|
@ -317,7 +325,7 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
// Ticket #3597
|
// Ticket #3597
|
||||||
checkUninitVar("int f() {\n"
|
checkUninitVar("void f() {\n"
|
||||||
" int a;\n"
|
" int a;\n"
|
||||||
" int b = 1;\n"
|
" int b = 1;\n"
|
||||||
" (b += a) = 1;\n"
|
" (b += a) = 1;\n"
|
||||||
|
@ -345,6 +353,7 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
// Unknown types
|
// Unknown types
|
||||||
|
// extracttests.disable
|
||||||
{
|
{
|
||||||
checkUninitVar("void a()\n"
|
checkUninitVar("void a()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -369,6 +378,7 @@ private:
|
||||||
"test.c", false);
|
"test.c", false);
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
}
|
}
|
||||||
|
// extracttests.enable
|
||||||
|
|
||||||
checkUninitVar("void a()\n"
|
checkUninitVar("void a()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -730,6 +740,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninitvar_warn_once() {
|
void uninitvar_warn_once() {
|
||||||
|
// extracttests.start: int a; int b;
|
||||||
|
|
||||||
checkUninitVar("void f() {\n"
|
checkUninitVar("void f() {\n"
|
||||||
" int x;\n"
|
" int x;\n"
|
||||||
" a = x;\n"
|
" a = x;\n"
|
||||||
|
@ -817,6 +829,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninitvar_bitop() {
|
void uninitvar_bitop() {
|
||||||
|
// extracttests.start: int a; int c;
|
||||||
|
|
||||||
checkUninitVar("void foo() {\n"
|
checkUninitVar("void foo() {\n"
|
||||||
" int b;\n"
|
" int b;\n"
|
||||||
" c = a | b;\n"
|
" c = a | b;\n"
|
||||||
|
@ -832,7 +846,8 @@ private:
|
||||||
|
|
||||||
// if..
|
// if..
|
||||||
void uninitvar_if() {
|
void uninitvar_if() {
|
||||||
checkUninitVar("static void foo()\n"
|
// extracttests.start: struct Foo { void abcd(); };
|
||||||
|
checkUninitVar("static void foo(int x)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" Foo *p;\n"
|
" Foo *p;\n"
|
||||||
" if (x)\n"
|
" if (x)\n"
|
||||||
|
@ -1148,6 +1163,7 @@ private:
|
||||||
// handling for/while loops..
|
// handling for/while loops..
|
||||||
void uninitvar_loops() {
|
void uninitvar_loops() {
|
||||||
// for..
|
// for..
|
||||||
|
// extracttests.start: void b(int);
|
||||||
checkUninitVar("void f()\n"
|
checkUninitVar("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" for (int i = 0; i < 4; ++i) {\n"
|
" for (int i = 0; i < 4; ++i) {\n"
|
||||||
|
@ -1211,7 +1227,8 @@ private:
|
||||||
" }\n"
|
" }\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
checkUninitVar("void f(int x) {\n"
|
// extracttests.start: struct PoolItem { bool operator!=(const PoolItem&) const; };
|
||||||
|
checkUninitVar("void f(int x, const PoolItem& rPool) {\n"
|
||||||
" const PoolItem* pItem;\n"
|
" const PoolItem* pItem;\n"
|
||||||
" while (x > 0) {\n"
|
" while (x > 0) {\n"
|
||||||
" if (*pItem != rPool)\n"
|
" if (*pItem != rPool)\n"
|
||||||
|
@ -1257,6 +1274,7 @@ private:
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
// #10273 - assignment in conditional code
|
// #10273 - assignment in conditional code
|
||||||
|
// extracttests.start: extern const int PORT_LEARN_DISABLE;
|
||||||
checkUninitVar("void foo() {\n"
|
checkUninitVar("void foo() {\n"
|
||||||
" int learn;\n"
|
" int learn;\n"
|
||||||
" for (int index = 0; index < 10; index++) {\n"
|
" for (int index = 0; index < 10; index++) {\n"
|
||||||
|
@ -1394,7 +1412,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
checkUninitVar("void f() {\n"
|
checkUninitVar("void f(int x) {\n"
|
||||||
" char a[10], c;\n"
|
" char a[10], c;\n"
|
||||||
" c = *(x?a:0);\n"
|
" c = *(x?a:0);\n"
|
||||||
"}");
|
"}");
|
||||||
|
@ -1420,7 +1438,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
checkUninitVar("void f() {\n"
|
checkUninitVar("void f(char *s2) {\n"
|
||||||
" char s[20];\n"
|
" char s[20];\n"
|
||||||
" strcpy(s2, s);\n"
|
" strcpy(s2, s);\n"
|
||||||
"};");
|
"};");
|
||||||
|
@ -1614,7 +1632,7 @@ private:
|
||||||
// alloc..
|
// alloc..
|
||||||
void uninitvar_alloc() {
|
void uninitvar_alloc() {
|
||||||
checkUninitVar("void f() {\n"
|
checkUninitVar("void f() {\n"
|
||||||
" char *s = malloc(100);\n"
|
" char *s = (char *)malloc(100);\n"
|
||||||
" strcat(s, \"abc\");\n"
|
" strcat(s, \"abc\");\n"
|
||||||
"};");
|
"};");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: s\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: s\n", errout.str());
|
||||||
|
@ -1628,19 +1646,19 @@ private:
|
||||||
|
|
||||||
checkUninitVar("void f()\n"
|
checkUninitVar("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char *p = malloc(64);\n"
|
" char *p = (char*)malloc(64);\n"
|
||||||
" int x = p[0];\n"
|
" int x = p[0];\n"
|
||||||
"}");
|
"}");
|
||||||
TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: p\n", "", errout.str());
|
TODO_ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: p\n", "", errout.str());
|
||||||
|
|
||||||
checkUninitVar("void f() {\n"
|
checkUninitVar("void f() {\n"
|
||||||
" char *p = malloc(64);\n"
|
" char *p = (char*)malloc(64);\n"
|
||||||
" if (p[0]) { }\n"
|
" if (p[0]) { }\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: p\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: p\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("void f() {\n"
|
checkUninitVar("char f() {\n"
|
||||||
" char *p = malloc(64);\n"
|
" char *p = (char*)malloc(64);\n"
|
||||||
" return p[0];\n"
|
" return p[0];\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: p\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: p\n", errout.str());
|
||||||
|
@ -1725,7 +1743,7 @@ private:
|
||||||
|
|
||||||
checkUninitVar("void f()\n"
|
checkUninitVar("void f()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char *s = malloc(100);\n"
|
" char *s = (char*)malloc(100);\n"
|
||||||
" if (!s)\n"
|
" if (!s)\n"
|
||||||
" return;\n"
|
" return;\n"
|
||||||
" char c = *s;\n"
|
" char c = *s;\n"
|
||||||
|
@ -2181,6 +2199,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: char str[10];
|
||||||
checkUninitVar("void f() {\n"
|
checkUninitVar("void f() {\n"
|
||||||
" int x;\n"
|
" int x;\n"
|
||||||
" str[x] = 0;\n"
|
" str[x] = 0;\n"
|
||||||
|
@ -2205,12 +2224,13 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("int f() {\n"
|
checkUninitVar("void f() {\n"
|
||||||
" int x;\n"
|
" int x;\n"
|
||||||
" x = x;\n"
|
" x = x;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: x\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: struct ABC {int a;};
|
||||||
checkUninitVar("void f() {\n"
|
checkUninitVar("void f() {\n"
|
||||||
" struct ABC *abc;\n"
|
" struct ABC *abc;\n"
|
||||||
" abc->a = 0;\n"
|
" abc->a = 0;\n"
|
||||||
|
@ -2813,6 +2833,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninitvar_funcptr() {
|
void uninitvar_funcptr() {
|
||||||
|
// extracttests.disable
|
||||||
|
|
||||||
checkUninitVar("void getLibraryContainer() {\n"
|
checkUninitVar("void getLibraryContainer() {\n"
|
||||||
" Reference< XStorageBasedLibraryContainer >(*Factory)(const Reference< XComponentContext >&, const Reference< XStorageBasedDocument >&)\n"
|
" Reference< XStorageBasedLibraryContainer >(*Factory)(const Reference< XComponentContext >&, const Reference< XStorageBasedDocument >&)\n"
|
||||||
" = &DocumentDialogLibraryContainer::create;\n"
|
" = &DocumentDialogLibraryContainer::create;\n"
|
||||||
|
@ -2832,6 +2854,8 @@ private:
|
||||||
" rxContainer.set((*Factory)(m_aContext, xDocument));\n"
|
" rxContainer.set((*Factory)(m_aContext, xDocument));\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: Factory\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: Factory\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.enable
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninitvar_operator() { // Ticket #6463, #6680
|
void uninitvar_operator() { // Ticket #6463, #6680
|
||||||
|
@ -2912,10 +2936,10 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: c\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: c\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("void a(const char c);\n" // const value => error
|
checkUninitVar("void a(const char *c);\n" // const value => error
|
||||||
"void b() {\n"
|
"void b() {\n"
|
||||||
" char c;\n"
|
" char c;\n"
|
||||||
" a(*c);\n"
|
" a(&c);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: c\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Uninitialized variable: c\n", errout.str());
|
||||||
|
|
||||||
|
@ -3014,6 +3038,7 @@ private:
|
||||||
ASSERT_EQUALS("[test.c:3]: (error) Uninitialized variable: now0\n", errout.str());
|
ASSERT_EQUALS("[test.c:3]: (error) Uninitialized variable: now0\n", errout.str());
|
||||||
|
|
||||||
// #2775 - uninitialized struct pointer in subfunction
|
// #2775 - uninitialized struct pointer in subfunction
|
||||||
|
// extracttests.start: struct Fred {int x;};
|
||||||
checkUninitVar("void a(struct Fred *fred) {\n"
|
checkUninitVar("void a(struct Fred *fred) {\n"
|
||||||
" fred->x = 0;\n"
|
" fred->x = 0;\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
|
@ -3111,10 +3136,11 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: int y;
|
||||||
checkUninitVar("int f(int x) {\n" // FP with ?:
|
checkUninitVar("int f(int x) {\n" // FP with ?:
|
||||||
" int a;\n"
|
" int a;\n"
|
||||||
" if (x)\n"
|
" if (x)\n"
|
||||||
" a = p;\n"
|
" a = y;\n"
|
||||||
" return x ? 2*a : 0;\n"
|
" return x ? 2*a : 0;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
@ -3122,7 +3148,7 @@ private:
|
||||||
checkUninitVar("int f(int x) {\n"
|
checkUninitVar("int f(int x) {\n"
|
||||||
" int a;\n"
|
" int a;\n"
|
||||||
" if (x)\n"
|
" if (x)\n"
|
||||||
" a = p;\n"
|
" a = y;\n"
|
||||||
" return y ? 2*a : 3*a;\n"
|
" return y ? 2*a : 3*a;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: a\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: a\n", errout.str());
|
||||||
|
@ -3253,7 +3279,7 @@ private:
|
||||||
"}\n", "test.c");
|
"}\n", "test.c");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
checkUninitVar("class Element {\n"
|
checkUninitVar("struct Element {\n"
|
||||||
" static void f() { }\n"
|
" static void f() { }\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"void test() {\n"
|
"void test() {\n"
|
||||||
|
@ -3261,7 +3287,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("class Element {\n"
|
checkUninitVar("struct Element {\n"
|
||||||
" static void f() { }\n"
|
" static void f() { }\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"void test() {\n"
|
"void test() {\n"
|
||||||
|
@ -3269,7 +3295,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("class Element {\n"
|
checkUninitVar("struct Element {\n"
|
||||||
" static int v;\n"
|
" static int v;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"void test() {\n"
|
"void test() {\n"
|
||||||
|
@ -3277,7 +3303,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("class Element {\n"
|
checkUninitVar("struct Element {\n"
|
||||||
" static int v;\n"
|
" static int v;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"void test() {\n"
|
"void test() {\n"
|
||||||
|
@ -3285,7 +3311,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("class Element {\n"
|
checkUninitVar("struct Element {\n"
|
||||||
" void f() { }\n"
|
" void f() { }\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"void test() {\n"
|
"void test() {\n"
|
||||||
|
@ -3293,7 +3319,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("class Element {\n"
|
checkUninitVar("struct Element {\n"
|
||||||
" void f() { }\n"
|
" void f() { }\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"void test() {\n"
|
"void test() {\n"
|
||||||
|
@ -3301,7 +3327,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("class Element {\n"
|
checkUninitVar("struct Element {\n"
|
||||||
" int v;\n"
|
" int v;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"void test() {\n"
|
"void test() {\n"
|
||||||
|
@ -3309,7 +3335,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized variable: element\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("class Element {\n"
|
checkUninitVar("struct Element {\n"
|
||||||
" int v;\n"
|
" int v;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"void test() {\n"
|
"void test() {\n"
|
||||||
|
@ -3688,6 +3714,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void uninitvar2_while() {
|
void uninitvar2_while() {
|
||||||
|
// extracttests.start: int a;
|
||||||
|
|
||||||
// for, while
|
// for, while
|
||||||
checkUninitVar("void f() {\n"
|
checkUninitVar("void f() {\n"
|
||||||
" int x;\n"
|
" int x;\n"
|
||||||
|
@ -3710,11 +3738,13 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error) Uninitialized variable: x\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (error) Uninitialized variable: x\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: struct Element{Element*Next();};
|
||||||
checkUninitVar("void f() {\n"
|
checkUninitVar("void f() {\n"
|
||||||
" for (Element *ptr3 = ptr3->Next(); ptr3; ptr3 = ptr3->Next()) {}\n"
|
" for (Element *ptr3 = ptr3->Next(); ptr3; ptr3 = ptr3->Next()) {}\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (error) Uninitialized variable: ptr3\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (error) Uninitialized variable: ptr3\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: int a;
|
||||||
checkUninitVar("void f() {\n"
|
checkUninitVar("void f() {\n"
|
||||||
" int x;\n"
|
" int x;\n"
|
||||||
" while (a) {\n"
|
" while (a) {\n"
|
||||||
|
@ -3785,6 +3815,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: void do_something(int);
|
||||||
checkUninitVar("void f(void) {\n"
|
checkUninitVar("void f(void) {\n"
|
||||||
" int x;\n"
|
" int x;\n"
|
||||||
" for (;;) {\n"
|
" for (;;) {\n"
|
||||||
|
@ -3856,7 +3887,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
checkUninitVar("int f() {\n"
|
checkUninitVar("void f() {\n"
|
||||||
" char *p = (char *)malloc(256);\n"
|
" char *p = (char *)malloc(256);\n"
|
||||||
" while(*p && *p == '_')\n"
|
" while(*p && *p == '_')\n"
|
||||||
" p++;\n"
|
" p++;\n"
|
||||||
|
@ -3870,6 +3901,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: int a;
|
||||||
checkUninitVar("void f() {\n" // No FN
|
checkUninitVar("void f() {\n" // No FN
|
||||||
" for (int i;;i++)\n"
|
" for (int i;;i++)\n"
|
||||||
" a=i;\n"
|
" a=i;\n"
|
||||||
|
@ -3942,20 +3974,20 @@ private:
|
||||||
|
|
||||||
void uninitvar2_malloc() {
|
void uninitvar2_malloc() {
|
||||||
checkUninitVar("int f() {\n"
|
checkUninitVar("int f() {\n"
|
||||||
" int *p = malloc(40);\n"
|
" int *p = (int*)malloc(40);\n"
|
||||||
" return *p;\n"
|
" return *p;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: p\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: p\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("int f() {\n"
|
checkUninitVar("void f() {\n"
|
||||||
" int *p = malloc(40);\n"
|
" int *p = (int*)malloc(40);\n"
|
||||||
" var = *p;\n"
|
" int var = *p;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: p\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Memory is allocated but not initialized: p\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("struct AB { int a; int b; };\n"
|
checkUninitVar("struct AB { int a; int b; };\n"
|
||||||
"int f() {\n"
|
"int f() {\n"
|
||||||
" struct AB *ab = malloc(sizeof(struct AB));\n"
|
" struct AB *ab = (AB*)malloc(sizeof(struct AB));\n"
|
||||||
" return ab->a;\n"
|
" return ab->a;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: ab\n"
|
ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: ab\n"
|
||||||
|
@ -3992,7 +4024,7 @@ private:
|
||||||
// function parameter (treat it as initialized until malloc is used)
|
// function parameter (treat it as initialized until malloc is used)
|
||||||
checkUninitVar("int f(int *p) {\n"
|
checkUninitVar("int f(int *p) {\n"
|
||||||
" if (*p == 1) {}\n" // no error
|
" if (*p == 1) {}\n" // no error
|
||||||
" p = malloc(256);\n"
|
" p = (int*)malloc(256);\n"
|
||||||
" return *p;\n" // error
|
" return *p;\n" // error
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: p\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (error) Memory is allocated but not initialized: p\n", errout.str());
|
||||||
|
@ -4000,15 +4032,15 @@ private:
|
||||||
checkUninitVar("struct AB { int a; int b; };\n"
|
checkUninitVar("struct AB { int a; int b; };\n"
|
||||||
"int f(struct AB *ab) {\n"
|
"int f(struct AB *ab) {\n"
|
||||||
" if (ab->a == 1) {}\n" // no error
|
" if (ab->a == 1) {}\n" // no error
|
||||||
" ab = malloc(sizeof(struct AB));\n"
|
" ab = (AB*)malloc(sizeof(struct AB));\n"
|
||||||
" return ab->a;\n" // error
|
" return ab->a;\n" // error
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized struct member: ab.a\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:5]: (error) Uninitialized struct member: ab.a\n", errout.str());
|
||||||
|
|
||||||
checkUninitVar("struct AB { int a; int b; };\n"
|
checkUninitVar("struct AB { int a; int b; };\n"
|
||||||
"void do_something(struct AB *ab);\n" // unknown function
|
"void do_something(struct AB *ab);\n" // unknown function
|
||||||
"int f() {\n"
|
"void f() {\n"
|
||||||
" struct AB *ab = malloc(sizeof(struct AB));\n"
|
" struct AB *ab = (AB*)malloc(sizeof(struct AB));\n"
|
||||||
" do_something(ab);\n"
|
" do_something(ab);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
@ -4744,6 +4776,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (error) Uninitialized variable: a\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: extern const int SIZE;
|
||||||
checkUninitVar("void f() {\n"
|
checkUninitVar("void f() {\n"
|
||||||
" char a[SIZE+10];\n"
|
" char a[SIZE+10];\n"
|
||||||
" char c = *a;\n"
|
" char c = *a;\n"
|
||||||
|
|
|
@ -1576,6 +1576,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void localvar1() {
|
void localvar1() {
|
||||||
|
// extracttests.disable
|
||||||
functionVariableUsage("void foo()\n"
|
functionVariableUsage("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int i = 0;\n"
|
" int i = 0;\n"
|
||||||
|
@ -2007,9 +2008,12 @@ private:
|
||||||
" int i = 0;\n"
|
" int i = 0;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'i' is assigned a value that is never used.\n", errout.str());
|
||||||
|
// extracttests.enable
|
||||||
}
|
}
|
||||||
|
|
||||||
void localvar2() {
|
void localvar2() {
|
||||||
|
// extracttests.start: struct undefined { void f(); };
|
||||||
|
|
||||||
functionVariableUsage("int foo()\n"
|
functionVariableUsage("int foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int i;\n"
|
" int i;\n"
|
||||||
|
@ -2032,6 +2036,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// extracttests.disable
|
||||||
functionVariableUsage("undefined foo()\n"
|
functionVariableUsage("undefined foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" undefined i;\n"
|
" undefined i;\n"
|
||||||
|
@ -2039,6 +2044,7 @@ private:
|
||||||
"}\n",
|
"}\n",
|
||||||
"test.c");
|
"test.c");
|
||||||
ASSERT_EQUALS("[test.c:3]: (style) Variable 'i' is not assigned a value.\n", errout.str());
|
ASSERT_EQUALS("[test.c:3]: (style) Variable 'i' is not assigned a value.\n", errout.str());
|
||||||
|
// extracttests.enable
|
||||||
|
|
||||||
functionVariableUsage("undefined *foo()\n"
|
functionVariableUsage("undefined *foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -2146,7 +2152,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void localvar3() {
|
void localvar3() {
|
||||||
functionVariableUsage("void foo()\n"
|
functionVariableUsage("void foo(int abc)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int i;\n"
|
" int i;\n"
|
||||||
" if ( abc )\n"
|
" if ( abc )\n"
|
||||||
|
@ -2225,6 +2231,8 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (style) Unused variable: i\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: struct A {int x;};
|
||||||
|
|
||||||
functionVariableUsage("void foo()\n"
|
functionVariableUsage("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" A * i;\n"
|
" A * i;\n"
|
||||||
|
@ -2384,6 +2392,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: int f();
|
||||||
functionVariableUsage("void foo()\n"
|
functionVariableUsage("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int a, b, c;\n"
|
" int a, b, c;\n"
|
||||||
|
@ -2527,6 +2536,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void localvar13() { // ticket #1640
|
void localvar13() { // ticket #1640
|
||||||
|
// extracttests.start: struct OBJECT { int ySize; };
|
||||||
functionVariableUsage("void foo( OBJECT *obj )\n"
|
functionVariableUsage("void foo( OBJECT *obj )\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int x;\n"
|
" int x;\n"
|
||||||
|
@ -2592,7 +2602,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void localvar16() { // ticket #1709
|
void localvar16() { // ticket #1709
|
||||||
functionVariableUsage("int foo()\n"
|
functionVariableUsage("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char buf[5];\n"
|
" char buf[5];\n"
|
||||||
" char *ptr = buf;\n"
|
" char *ptr = buf;\n"
|
||||||
|
@ -2600,7 +2610,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
|
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
|
||||||
|
|
||||||
functionVariableUsage("int foo()\n"
|
functionVariableUsage("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char buf[5];\n"
|
" char buf[5];\n"
|
||||||
" char *ptr = buf - 1;\n"
|
" char *ptr = buf - 1;\n"
|
||||||
|
@ -2609,7 +2619,7 @@ private:
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'buf' is not assigned a value.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'buf' is not assigned a value.\n", errout.str());
|
||||||
|
|
||||||
// #3910
|
// #3910
|
||||||
functionVariableUsage("int foo() {\n"
|
functionVariableUsage("void foo() {\n"
|
||||||
" char buf[5];\n"
|
" char buf[5];\n"
|
||||||
" char *data[2];\n"
|
" char *data[2];\n"
|
||||||
" data[0] = buf;\n"
|
" data[0] = buf;\n"
|
||||||
|
@ -2617,7 +2627,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
functionVariableUsage("int foo() {\n"
|
functionVariableUsage("void foo() {\n"
|
||||||
" char buf1[5];\n"
|
" char buf1[5];\n"
|
||||||
" char buf2[5];\n"
|
" char buf2[5];\n"
|
||||||
" char *data[2];\n"
|
" char *data[2];\n"
|
||||||
|
@ -2629,6 +2639,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void localvar17() { // ticket #1720
|
void localvar17() { // ticket #1720
|
||||||
|
// extracttests.disable
|
||||||
// Don't crash when checking the code below!
|
// Don't crash when checking the code below!
|
||||||
functionVariableUsage("void foo()\n"
|
functionVariableUsage("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -2642,6 +2653,7 @@ private:
|
||||||
" line_start = ptr;\n"
|
" line_start = ptr;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:10]: (style) Variable 'line_start' is assigned a value that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:10]: (style) Variable 'line_start' is assigned a value that is never used.\n", errout.str());
|
||||||
|
// extracttests.enable
|
||||||
}
|
}
|
||||||
|
|
||||||
void localvar18() { // ticket #1723
|
void localvar18() { // ticket #1723
|
||||||
|
@ -3028,11 +3040,13 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void localvar47() { // #6603
|
void localvar47() { // #6603
|
||||||
|
// extracttests.disable
|
||||||
functionVariableUsage("void f() {\n"
|
functionVariableUsage("void f() {\n"
|
||||||
" int (SfxUndoManager::*retrieveCount)(bool) const\n"
|
" int (SfxUndoManager::*retrieveCount)(bool) const\n"
|
||||||
" = (flag) ? &SfxUndoManager::foo : &SfxUndoManager::bar;\n"
|
" = (flag) ? &SfxUndoManager::foo : &SfxUndoManager::bar;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'retrieveCount' is assigned a value that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'retrieveCount' is assigned a value that is never used.\n", errout.str());
|
||||||
|
// extracttests.enable
|
||||||
}
|
}
|
||||||
|
|
||||||
void localvar48() { // #6954
|
void localvar48() { // #6954
|
||||||
|
@ -3087,8 +3101,9 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void localvar51() { // #8128 FN
|
void localvar51() { // #8128 FN
|
||||||
functionVariableUsage("void foo() {\n"
|
// extracttests.start: struct Token { const Token* next() const; }; const Token* nameToken();
|
||||||
" const char *tok = var->nameToken();\n"
|
functionVariableUsage("void foo(const Token *var) {\n"
|
||||||
|
" const Token *tok = nameToken();\n"
|
||||||
" tok = tok->next();\n" // read+write
|
" tok = tok->next();\n" // read+write
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'tok' is assigned a value that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'tok' is assigned a value that is never used.\n", errout.str());
|
||||||
|
@ -3110,7 +3125,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void localvar53() {
|
void localvar53() {
|
||||||
functionVariableUsage("void foo() {\n"
|
functionVariableUsage("void foo(int a, int loop) {\n"
|
||||||
" bool x = false;\n"
|
" bool x = false;\n"
|
||||||
" while (loop) {\n"
|
" while (loop) {\n"
|
||||||
" if (a) {\n"
|
" if (a) {\n"
|
||||||
|
@ -3121,7 +3136,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
|
||||||
|
|
||||||
functionVariableUsage("void foo() {\n"
|
functionVariableUsage("void foo(int a, int loop) {\n"
|
||||||
" bool x = false;\n"
|
" bool x = false;\n"
|
||||||
" while (loop) {\n"
|
" while (loop) {\n"
|
||||||
" if (a) {\n"
|
" if (a) {\n"
|
||||||
|
@ -3202,14 +3217,14 @@ private:
|
||||||
|
|
||||||
void localvarloops() {
|
void localvarloops() {
|
||||||
// loops
|
// loops
|
||||||
functionVariableUsage("void fun() {\n"
|
functionVariableUsage("void fun(int c) {\n"
|
||||||
" int x;\n"
|
" int x;\n"
|
||||||
" while (c) { x=10; }\n"
|
" while (c) { x=10; }\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'x' is assigned a value that is never used.\n", errout.str());
|
||||||
|
|
||||||
functionVariableUsage("void dostuff(int x);\n"
|
functionVariableUsage("void dostuff(int x);\n"
|
||||||
"void fun() {\n"
|
"void fun(int y, int c) {\n"
|
||||||
" int x = 1;\n"
|
" int x = 1;\n"
|
||||||
" while (c) {\n"
|
" while (c) {\n"
|
||||||
" dostuff(x);\n"
|
" dostuff(x);\n"
|
||||||
|
@ -3357,7 +3372,7 @@ private:
|
||||||
" {\n"
|
" {\n"
|
||||||
" int *b = &a;\n"
|
" int *b = &a;\n"
|
||||||
" }\n"
|
" }\n"
|
||||||
"}");
|
"};");
|
||||||
ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'b' is assigned a value that is never used.\n", errout.str());
|
||||||
|
|
||||||
functionVariableUsage("int a;\n"
|
functionVariableUsage("int a;\n"
|
||||||
|
@ -3475,6 +3490,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: int a[10];
|
||||||
functionVariableUsage("void foo()\n"
|
functionVariableUsage("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int *b = a;\n"
|
" int *b = a;\n"
|
||||||
|
@ -3601,6 +3617,7 @@ private:
|
||||||
ASSERT_EQUALS(// TODO "[test.cpp:4]: (style) Variable 'a' is assigned a value that is never used.\n"
|
ASSERT_EQUALS(// TODO "[test.cpp:4]: (style) Variable 'a' is assigned a value that is never used.\n"
|
||||||
"[test.cpp:5]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
|
"[test.cpp:5]: (style) Variable 'c' is assigned a value that is never used.\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: int x;
|
||||||
functionVariableUsage("void foo()\n"
|
functionVariableUsage("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int a[10], * b = a + 10;\n"
|
" int a[10], * b = a + 10;\n"
|
||||||
|
@ -3625,6 +3642,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'c[1]' is assigned a value that is never used.\n", errout.str());
|
// TODO ASSERT_EQUALS("[test.cpp:5]: (style) Variable 'c[1]' is assigned a value that is never used.\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: void f(int);
|
||||||
functionVariableUsage("void foo()\n"
|
functionVariableUsage("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int a[10], * b = a + 10;\n"
|
" int a[10], * b = a + 10;\n"
|
||||||
|
@ -3819,6 +3837,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void localvaralias6() { // ticket 1729
|
void localvaralias6() { // ticket 1729
|
||||||
|
// extracttests.start: int a(); void b(const char *);
|
||||||
functionVariableUsage("void foo()\n"
|
functionVariableUsage("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char buf[8];\n"
|
" char buf[8];\n"
|
||||||
|
@ -3859,7 +3878,7 @@ private:
|
||||||
"}");
|
"}");
|
||||||
// TODO ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
|
// TODO ASSERT_EQUALS("[test.cpp:6]: (style) Variable 'buf' is assigned a value that is never used.\n", errout.str());
|
||||||
|
|
||||||
functionVariableUsage("void foo()\n"
|
functionVariableUsage("void foo(char *vdata)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char buf[8];\n"
|
" char buf[8];\n"
|
||||||
" char *srcdata;\n"
|
" char *srcdata;\n"
|
||||||
|
@ -4336,6 +4355,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void localvarStruct5() {
|
void localvarStruct5() {
|
||||||
|
// extracttests.disable
|
||||||
functionVariableUsage("int foo() {\n"
|
functionVariableUsage("int foo() {\n"
|
||||||
" A a;\n"
|
" A a;\n"
|
||||||
" return a.i;\n"
|
" return a.i;\n"
|
||||||
|
@ -4354,6 +4374,7 @@ private:
|
||||||
"}\n",
|
"}\n",
|
||||||
"test.c");
|
"test.c");
|
||||||
ASSERT_EQUALS("[test.c:2]: (style) Unused variable: a\n", errout.str());
|
ASSERT_EQUALS("[test.c:2]: (style) Unused variable: a\n", errout.str());
|
||||||
|
// extracttests.enable
|
||||||
|
|
||||||
functionVariableUsage("struct A { int i; };\n"
|
functionVariableUsage("struct A { int i; };\n"
|
||||||
"int foo() {\n"
|
"int foo() {\n"
|
||||||
|
@ -4362,13 +4383,6 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
functionVariableUsage("class A { int i; };\n"
|
|
||||||
"int foo() {\n"
|
|
||||||
" A a;\n"
|
|
||||||
" return a.i;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
|
|
||||||
functionVariableUsage("struct A { int i; };\n"
|
functionVariableUsage("struct A { int i; };\n"
|
||||||
"int foo() {\n"
|
"int foo() {\n"
|
||||||
" A a;\n"
|
" A a;\n"
|
||||||
|
@ -4377,14 +4391,6 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a.i' is assigned a value that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a.i' is assigned a value that is never used.\n", errout.str());
|
||||||
|
|
||||||
functionVariableUsage("class A { int i; };\n"
|
|
||||||
"int foo() {\n"
|
|
||||||
" A a;\n"
|
|
||||||
" a.i = 0;\n"
|
|
||||||
" return 0;\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'a.i' is assigned a value that is never used.\n", errout.str());
|
|
||||||
|
|
||||||
functionVariableUsage("struct A { int i; };\n"
|
functionVariableUsage("struct A { int i; };\n"
|
||||||
"int foo() {\n"
|
"int foo() {\n"
|
||||||
" A a = { 0 };\n"
|
" A a = { 0 };\n"
|
||||||
|
@ -4392,12 +4398,14 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.disable
|
||||||
functionVariableUsage("class A { int i; };\n"
|
functionVariableUsage("class A { int i; };\n"
|
||||||
"int foo() {\n"
|
"int foo() {\n"
|
||||||
" A a = { 0 };\n"
|
" A a = { 0 };\n"
|
||||||
" return 0;\n"
|
" return 0;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'a' is assigned a value that is never used.\n", errout.str());
|
||||||
|
// extracttests.enable
|
||||||
|
|
||||||
functionVariableUsage("class A { int i; public: A(); { } };\n"
|
functionVariableUsage("class A { int i; public: A(); { } };\n"
|
||||||
"int foo() {\n"
|
"int foo() {\n"
|
||||||
|
@ -4474,9 +4482,10 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// extracttests.start: void dostuff(int*);
|
||||||
functionVariableUsage("struct ARG {\n"
|
functionVariableUsage("struct ARG {\n"
|
||||||
" void *a;\n"
|
" int a;\n"
|
||||||
" void *b;\n"
|
" int b;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"\n"
|
"\n"
|
||||||
"void fun() {\n"
|
"void fun() {\n"
|
||||||
|
@ -4533,7 +4542,7 @@ private:
|
||||||
void localvarStruct10() { // #6766
|
void localvarStruct10() { // #6766
|
||||||
functionVariableUsage("struct S { int x; };\n"
|
functionVariableUsage("struct S { int x; };\n"
|
||||||
"\n"
|
"\n"
|
||||||
"void foo() {\n"
|
"void foo(const struct S s2) {\n"
|
||||||
" struct S s;\n"
|
" struct S s;\n"
|
||||||
" s.x = 3;\n"
|
" s.x = 3;\n"
|
||||||
" memcpy (&s, &s2, sizeof (S));\n"
|
" memcpy (&s, &s2, sizeof (S));\n"
|
||||||
|
@ -4542,6 +4551,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void localvarStructArray() {
|
void localvarStructArray() {
|
||||||
|
// extracttests.start: struct X {int a;};
|
||||||
|
|
||||||
// #3633 - detect that struct array is assigned a value
|
// #3633 - detect that struct array is assigned a value
|
||||||
functionVariableUsage("void f() {\n"
|
functionVariableUsage("void f() {\n"
|
||||||
" struct X x[10];\n"
|
" struct X x[10];\n"
|
||||||
|
@ -4674,14 +4685,16 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("", errout.str());
|
ASSERT_EQUALS("", errout.str());
|
||||||
|
|
||||||
|
// extracttests.disable
|
||||||
functionVariableUsage("void f() {\n" // unknown class => library configuration is needed
|
functionVariableUsage("void f() {\n" // unknown class => library configuration is needed
|
||||||
" Fred fred;\n"
|
" Fred fred;\n"
|
||||||
" int *a; a = b;\n"
|
" int *a; a = b;\n"
|
||||||
" fred += a;\n"
|
" fred += a;\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (information) --check-library: Provide <type-checks><unusedvar> configuration for Fred\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (information) --check-library: Provide <type-checks><unusedvar> configuration for Fred\n", errout.str());
|
||||||
|
// extracttests.enable
|
||||||
|
|
||||||
functionVariableUsage("void f() {\n"
|
functionVariableUsage("void f(std::pair<int,int> x) {\n"
|
||||||
" std::pair<int,int> fred;\n" // class with library configuration
|
" std::pair<int,int> fred;\n" // class with library configuration
|
||||||
" fred = x;\n"
|
" fred = x;\n"
|
||||||
"}");
|
"}");
|
||||||
|
@ -4896,28 +4909,6 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
||||||
|
|
||||||
functionVariableUsage("void foo()\n"
|
|
||||||
"{\n"
|
|
||||||
" void* ptr = g_malloc(16);\n"
|
|
||||||
" g_free(ptr);\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
|
||||||
|
|
||||||
functionVariableUsage("void foo()\n"
|
|
||||||
"{\n"
|
|
||||||
" void* ptr = kmalloc(16, GFP_KERNEL);\n"
|
|
||||||
" kfree(ptr);\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
|
||||||
|
|
||||||
functionVariableUsage("void foo()\n"
|
|
||||||
"{\n"
|
|
||||||
" void* ptr = vmalloc(16, GFP_KERNEL);\n"
|
|
||||||
" vfree(ptr);\n"
|
|
||||||
"}");
|
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
|
||||||
|
|
||||||
|
|
||||||
functionVariableUsage("void foo()\n"
|
functionVariableUsage("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char* ptr = new char[16];\n"
|
" char* ptr = new char[16];\n"
|
||||||
|
@ -4925,6 +4916,8 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.disable
|
||||||
|
|
||||||
functionVariableUsage("void foo()\n"
|
functionVariableUsage("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char* ptr = new ( nothrow ) char[16];\n"
|
" char* ptr = new ( nothrow ) char[16];\n"
|
||||||
|
@ -4939,6 +4932,8 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:3]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.enable
|
||||||
|
|
||||||
functionVariableUsage("void foo()\n"
|
functionVariableUsage("void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" char* ptr = new char;\n"
|
" char* ptr = new char;\n"
|
||||||
|
@ -5009,7 +5004,7 @@ private:
|
||||||
functionVariableUsage("struct Fred { int i; };\n"
|
functionVariableUsage("struct Fred { int i; };\n"
|
||||||
"void foo()\n"
|
"void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" Fred* ptr = malloc(sizeof(Fred));\n"
|
" Fred* ptr = (Fred*)malloc(sizeof(Fred));\n"
|
||||||
" free(ptr);\n"
|
" free(ptr);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
||||||
|
@ -5017,7 +5012,7 @@ private:
|
||||||
functionVariableUsage("struct Fred { int i; };\n"
|
functionVariableUsage("struct Fred { int i; };\n"
|
||||||
"void foo()\n"
|
"void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" Fred* ptr = malloc(sizeof(Fred));\n"
|
" Fred* ptr = (Fred*)malloc(sizeof(Fred));\n"
|
||||||
" ptr->i = 0;\n"
|
" ptr->i = 0;\n"
|
||||||
" free(ptr);\n"
|
" free(ptr);\n"
|
||||||
"}");
|
"}");
|
||||||
|
@ -5026,7 +5021,7 @@ private:
|
||||||
functionVariableUsage("struct Fred { int i; };\n"
|
functionVariableUsage("struct Fred { int i; };\n"
|
||||||
"void foo()\n"
|
"void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" struct Fred* ptr = malloc(sizeof(Fred));\n"
|
" struct Fred* ptr = (Fred*)malloc(sizeof(Fred));\n"
|
||||||
" free(ptr);\n"
|
" free(ptr);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
||||||
|
@ -5034,7 +5029,7 @@ private:
|
||||||
functionVariableUsage("struct Fred { int i; };\n"
|
functionVariableUsage("struct Fred { int i; };\n"
|
||||||
"void foo()\n"
|
"void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" struct Fred* ptr = malloc(sizeof(Fred));\n"
|
" struct Fred* ptr = (Fred*)malloc(sizeof(Fred));\n"
|
||||||
" ptr->i = 0;\n"
|
" ptr->i = 0;\n"
|
||||||
" free(ptr);\n"
|
" free(ptr);\n"
|
||||||
"}");
|
"}");
|
||||||
|
@ -5048,6 +5043,8 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.disable
|
||||||
|
|
||||||
functionVariableUsage("struct Fred { int i; };\n"
|
functionVariableUsage("struct Fred { int i; };\n"
|
||||||
"void foo()\n"
|
"void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -5064,6 +5061,8 @@ private:
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
||||||
|
|
||||||
|
// extracttests.enable
|
||||||
|
|
||||||
functionVariableUsage("struct Fred { int i; };\n"
|
functionVariableUsage("struct Fred { int i; };\n"
|
||||||
"void foo()\n"
|
"void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
|
@ -5093,7 +5092,7 @@ private:
|
||||||
functionVariableUsage("class Fred { public: int i; };\n"
|
functionVariableUsage("class Fred { public: int i; };\n"
|
||||||
"void foo()\n"
|
"void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" Fred* ptr = malloc(sizeof(Fred));\n"
|
" Fred* ptr = (Fred*)malloc(sizeof(Fred));\n"
|
||||||
" free(ptr);\n"
|
" free(ptr);\n"
|
||||||
"}");
|
"}");
|
||||||
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
ASSERT_EQUALS("[test.cpp:4]: (style) Variable 'ptr' is allocated memory that is never used.\n", errout.str());
|
||||||
|
@ -5101,7 +5100,7 @@ private:
|
||||||
functionVariableUsage("class Fred { public: int i; };\n"
|
functionVariableUsage("class Fred { public: int i; };\n"
|
||||||
"void foo()\n"
|
"void foo()\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" Fred* ptr = malloc(sizeof(Fred));\n"
|
" Fred* ptr = (Fred*)malloc(sizeof(Fred));\n"
|
||||||
" ptr->i = 0;\n"
|
" ptr->i = 0;\n"
|
||||||
" free(ptr);\n"
|
" free(ptr);\n"
|
||||||
"}");
|
"}");
|
||||||
|
@ -5344,6 +5343,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void localVarStd() {
|
void localVarStd() {
|
||||||
|
// extracttests.start: struct MyClass {int x;}; std::string foo();
|
||||||
|
|
||||||
functionVariableUsage("void f() {\n"
|
functionVariableUsage("void f() {\n"
|
||||||
" std::string x = foo();\n"
|
" std::string x = foo();\n"
|
||||||
"}");
|
"}");
|
||||||
|
|
|
@ -26,6 +26,43 @@ import sys
|
||||||
import re
|
import re
|
||||||
|
|
||||||
|
|
||||||
|
def add_includes(code):
|
||||||
|
includes = (('alloca','alloca.h'),
|
||||||
|
('NULL','cstddef'),
|
||||||
|
('size_t','cstddef'),
|
||||||
|
('free','cstdlib'),
|
||||||
|
('malloc','cstdlib'),
|
||||||
|
('realloc','cstdlib'),
|
||||||
|
('stdin','cstdio'),
|
||||||
|
('strcat','cstring'),
|
||||||
|
('strchr','cstring'),
|
||||||
|
('strcpy','cstring'),
|
||||||
|
('strlen','cstring'),
|
||||||
|
('strncat','cstring'),
|
||||||
|
('strncpy','cstring'),
|
||||||
|
('std::cout','iostream'),
|
||||||
|
('std::shared_ptr','memory'),
|
||||||
|
('std::string','string'),
|
||||||
|
('std::unique_ptr','memory'))
|
||||||
|
|
||||||
|
for i in includes:
|
||||||
|
if i[0] in code:
|
||||||
|
include_header = f'#include <{i[1]}>'
|
||||||
|
if include_header not in code:
|
||||||
|
code = include_header + '\n' + code
|
||||||
|
|
||||||
|
return code
|
||||||
|
|
||||||
|
|
||||||
|
def tweak_expected(expected, start_code):
|
||||||
|
if start_code is None:
|
||||||
|
return expected
|
||||||
|
res = re.match(r'\[([^:\]]+):([0-9]+)\](.*)', expected)
|
||||||
|
if res is None:
|
||||||
|
return expected
|
||||||
|
lines = len(start_code.split('\n'))
|
||||||
|
return '[%s:%i]%s' % (res.group(1), lines + int(res.group(2)), res.group(3))
|
||||||
|
|
||||||
class Extract:
|
class Extract:
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
@ -48,6 +85,8 @@ class Extract:
|
||||||
testclass = None
|
testclass = None
|
||||||
functionName = None
|
functionName = None
|
||||||
code = None
|
code = None
|
||||||
|
start_code = None
|
||||||
|
disable = False
|
||||||
|
|
||||||
fin = open(filename, 'r')
|
fin = open(filename, 'r')
|
||||||
for line in fin:
|
for line in fin:
|
||||||
|
@ -64,31 +103,47 @@ class Extract:
|
||||||
res = re.match('\\s+void (' + name + ')\\(\\)', line)
|
res = re.match('\\s+void (' + name + ')\\(\\)', line)
|
||||||
if res is not None:
|
if res is not None:
|
||||||
functionName = res.group(1)
|
functionName = res.group(1)
|
||||||
|
start_code = None
|
||||||
|
|
||||||
elif re.match('\\s+}', line) is not None:
|
elif re.match('\\s+}', line) is not None:
|
||||||
functionName = None
|
functionName = None
|
||||||
|
|
||||||
if functionName is None:
|
# extracttests commands..
|
||||||
|
res = re.match(r'\s*//\s*extracttests.start:(.*)', line)
|
||||||
|
if res is not None:
|
||||||
|
start_code = res.group(1).replace('\\n', '\n')
|
||||||
|
elif line.find('extracttests.disable') >= 0:
|
||||||
|
disable = True
|
||||||
|
elif line.find('extracttests.enable') >= 0:
|
||||||
|
disable = False
|
||||||
|
|
||||||
|
if functionName is None or disable:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# check
|
# check
|
||||||
res = re.match('\\s+check.*\\(' + string, line)
|
res = re.match('\\s+' + check_function + '\\(' + string, line)
|
||||||
if res is not None:
|
if res is not None:
|
||||||
code = res.group(1)
|
code = res.group(1)
|
||||||
|
if start_code:
|
||||||
|
code = start_code + '\n' + code
|
||||||
|
|
||||||
# code..
|
# code..
|
||||||
if code is not None:
|
if code is not None:
|
||||||
res = re.match('\\s+' + string, line)
|
res = re.match('\\s+' + string, line)
|
||||||
if res is not None:
|
if res is not None:
|
||||||
code = code + res.group(1)
|
code = code + res.group(1)
|
||||||
|
if res.group(1).find('"') > 0:
|
||||||
|
code = None
|
||||||
|
|
||||||
# assert
|
# assert
|
||||||
res = re.match('\\s+ASSERT_EQUALS\\(\\"([^"]*)\\",', line)
|
res = re.match('\\s+ASSERT_EQUALS\\(\\"([^"]*)\\",', line)
|
||||||
if res is not None and code is not None:
|
if res is not None and code is not None:
|
||||||
|
code = add_includes(code)
|
||||||
|
expected = tweak_expected(res.group(1), start_code)
|
||||||
node = {'testclass': testclass,
|
node = {'testclass': testclass,
|
||||||
'functionName': functionName,
|
'functionName': functionName,
|
||||||
'code': code,
|
'code': code.replace("\\\\", "\\"),
|
||||||
'expected': res.group(1)}
|
'expected': expected}
|
||||||
self.nodes.append(node)
|
self.nodes.append(node)
|
||||||
code = None
|
code = None
|
||||||
|
|
||||||
|
@ -165,7 +220,7 @@ def writeHtmlFile(nodes, functionName, filename, errorsOnly):
|
||||||
if len(sys.argv) <= 1 or '--help' in sys.argv:
|
if len(sys.argv) <= 1 or '--help' in sys.argv:
|
||||||
print('Extract test cases from test file')
|
print('Extract test cases from test file')
|
||||||
print(
|
print(
|
||||||
'Syntax: extracttests.py [--html=folder] [--xml] [--code=folder] [--onlyTP] path/testfile.cpp')
|
'Syntax: extracttests.py [--html=folder] [--xml] [--code=folder] [--only-tp] [--check-function=check] path/testfile.cpp')
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
# parse command line
|
# parse command line
|
||||||
|
@ -174,10 +229,11 @@ filename = None
|
||||||
htmldir = None
|
htmldir = None
|
||||||
codedir = None
|
codedir = None
|
||||||
onlyTP = None
|
onlyTP = None
|
||||||
|
check_function = 'check.*'
|
||||||
for arg in sys.argv[1:]:
|
for arg in sys.argv[1:]:
|
||||||
if arg == '--xml':
|
if arg == '--xml':
|
||||||
xml = True
|
xml = True
|
||||||
elif arg == '--onlyTP':
|
elif arg == '--only-tp':
|
||||||
onlyTP = True
|
onlyTP = True
|
||||||
elif arg.startswith('--html='):
|
elif arg.startswith('--html='):
|
||||||
htmldir = arg[7:]
|
htmldir = arg[7:]
|
||||||
|
@ -185,6 +241,8 @@ for arg in sys.argv[1:]:
|
||||||
codedir = arg[7:]
|
codedir = arg[7:]
|
||||||
elif arg.endswith('.cpp'):
|
elif arg.endswith('.cpp'):
|
||||||
filename = arg
|
filename = arg
|
||||||
|
elif arg.startswith('--check-function='):
|
||||||
|
check_function = arg[17:]
|
||||||
else:
|
else:
|
||||||
print('Invalid option: ' + arg)
|
print('Invalid option: ' + arg)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
@ -286,6 +344,11 @@ if filename is not None:
|
||||||
|
|
||||||
errors = open(codedir + 'errors.txt', 'w')
|
errors = open(codedir + 'errors.txt', 'w')
|
||||||
|
|
||||||
|
testfile = filename
|
||||||
|
if testfile.find('/'):
|
||||||
|
testfile = testfile[testfile.rfind('/'):]
|
||||||
|
testfile = testfile[:testfile.find('.')]
|
||||||
|
|
||||||
for node in e.nodes:
|
for node in e.nodes:
|
||||||
if onlyTP and node['expected'] == '':
|
if onlyTP and node['expected'] == '':
|
||||||
continue
|
continue
|
||||||
|
@ -298,14 +361,11 @@ if filename is not None:
|
||||||
code = code.replace('\\"', '"')
|
code = code.replace('\\"', '"')
|
||||||
expected = node['expected']
|
expected = node['expected']
|
||||||
|
|
||||||
filename = '0000' + str(testnum) + '-'
|
filename = '%s-%03i-%s.cpp' % (testfile, testnum, functionName)
|
||||||
filename = filename[-4:]
|
|
||||||
filename += functionName + '.cpp'
|
|
||||||
|
|
||||||
# source code
|
# source code
|
||||||
fout = open(codedir + filename, 'w')
|
with open(codedir + filename, 'w') as fout:
|
||||||
fout.write(code)
|
fout.write(code)
|
||||||
fout.close()
|
|
||||||
|
|
||||||
# write 'expected' to errors.txt
|
# write 'expected' to errors.txt
|
||||||
if expected != '':
|
if expected != '':
|
||||||
|
|
Loading…
Reference in New Issue