Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Partial fix for #12468 Library functions not handled in assertWithSideEffect check #6364

Merged
merged 16 commits into from
Apr 30, 2024
1 change: 1 addition & 0 deletions cfg/gtk.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -4112,6 +4112,7 @@
<!-- int g_strcmp0 (const char *str1, const char *str2); -->
<function name="g_strcmp0">
<leak-ignore/>
<pure/>
<noreturn>false</noreturn>
<returnValue type="int"/>
<use-retval/>
Expand Down
11 changes: 10 additions & 1 deletion lib/checkassert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,25 @@ void CheckAssert::assertWithSideEffects()
for (const Token* tok = mTokenizer->list.front(); tok; tok = tok->next()) {
if (!Token::simpleMatch(tok, "assert ("))
continue;
if (Token::Match(tok->next()->astOperand1(), "%cop%")) // bailout
continue;

const Token *endTok = tok->next()->link();
for (const Token* tmp = tok->next(); tmp != endTok; tmp = tmp->next()) {
if (Token::simpleMatch(tmp, "sizeof ("))
tmp = tmp->linkAt(1);
if (findLambdaEndToken(tmp)) // bailout
continue;

checkVariableAssignment(tmp, tok->scope());

if (tmp->tokType() != Token::eFunction)
if (tmp->tokType() != Token::eFunction) {
if (const Library::Function* f = mSettings->library.getFunction(tmp)) {
if (!f->isconst && !f->ispure)
sideEffectInAssertError(tmp, mSettings->library.getFunctionName(tmp));
}
continue;
}

const Function* f = tmp->function();
const Scope* scope = f->functionScope;
Expand Down
1 change: 1 addition & 0 deletions test/cfg/gtk.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ void validCode(int argInt, GHashTableIter * hash_table_iter, GHashTable * hash_t
// NULL is handled graciously
char* str = g_strdup(NULL);
if (g_strcmp0(str, NULL) || g_strcmp0(NULL, str))
// cppcheck-suppress valueFlowBailout // TODO: caused by <pure/>?
printf("%s", str);
g_free(str);
}
Expand Down
6 changes: 6 additions & 0 deletions test/cfg/std.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5016,3 +5016,9 @@ void eraseIteratorOutOfBounds_std_deque(std::deque<int>& x) // #8690
// cppcheck-suppress eraseIteratorOutOfBounds
x.erase(x.end());
}

void assertWithSideEffect_system()
{
// cppcheck-suppress [assertWithSideEffect,checkLibraryNoReturn] // TODO: #8329
assert(std::system("abc"));
}
Loading