Detect more non-interlocked accesses
This commit is contained in:
parent
508b06abaa
commit
8f8a0097fe
|
@ -2418,6 +2418,24 @@ void CheckOther::checkInterlockedDecrement()
|
|||
(Token::Match(checkStartTok, "%name% %comp% 0 )") && checkStartTok->str() == interlockedVarTok->str())) {
|
||||
raceAfterInterlockedDecrementError(checkStartTok);
|
||||
}
|
||||
} else if (Token::Match(tok, "if ( ::| InterlockedDecrement ( & %name%")) {
|
||||
const Token* condEnd = tok->next()->link();
|
||||
const Token* funcTok = tok->tokAt(2);
|
||||
const Token* firstAccessTok = funcTok->str() == "::" ? funcTok->tokAt(4) : funcTok->tokAt(3);
|
||||
if (condEnd && condEnd->next() && condEnd->next()->link()) {
|
||||
const Token* ifEndTok = condEnd->next()->link();
|
||||
if (Token::Match(ifEndTok, "} return %name%")) {
|
||||
const Token* secondAccessTok = ifEndTok->tokAt(2);
|
||||
if (secondAccessTok->str() == firstAccessTok->str()) {
|
||||
raceAfterInterlockedDecrementError(secondAccessTok);
|
||||
}
|
||||
} else if (Token::Match(ifEndTok, "} else { return %name%")) {
|
||||
const Token* secondAccessTok = ifEndTok->tokAt(4);
|
||||
if (secondAccessTok->str() == firstAccessTok->str()) {
|
||||
raceAfterInterlockedDecrementError( secondAccessTok );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5971,6 +5971,77 @@ private:
|
|||
" destroy;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
checkInterlockedDecrement(
|
||||
"int f() {\n"
|
||||
" int counter = 0;\n"
|
||||
" if (InterlockedDecrement(&counter) == 0) {\n"
|
||||
" destroy();\n"
|
||||
" return 0;\n"
|
||||
" } else {\n"
|
||||
" return counter;\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:7]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead.\n", errout.str());
|
||||
|
||||
checkInterlockedDecrement(
|
||||
"int f() {\n"
|
||||
" int counter = 0;\n"
|
||||
" if (::InterlockedDecrement(&counter) == 0) {\n"
|
||||
" destroy();\n"
|
||||
" return 0;\n"
|
||||
" } else {\n"
|
||||
" return counter;\n"
|
||||
" }\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:7]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead.\n", errout.str());
|
||||
|
||||
|
||||
checkInterlockedDecrement(
|
||||
"int f() {\n"
|
||||
" int counter = 0;\n"
|
||||
" if (InterlockedDecrement(&counter) == 0) {\n"
|
||||
" destroy();\n"
|
||||
" return 0;\n"
|
||||
" }\n"
|
||||
" return counter;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:7]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead.\n", errout.str());
|
||||
|
||||
checkInterlockedDecrement(
|
||||
"int f() {\n"
|
||||
" int counter = 0;\n"
|
||||
" if (::InterlockedDecrement(&counter) == 0) {\n"
|
||||
" destroy();\n"
|
||||
" return 0;\n"
|
||||
" }\n"
|
||||
" return counter;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:7]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead.\n", errout.str());
|
||||
|
||||
checkInterlockedDecrement(
|
||||
"int f() {\n"
|
||||
" int counter = 0;\n"
|
||||
" if (InterlockedDecrement(&counter) == 0) {\n"
|
||||
" destroy();\n"
|
||||
" return 0;\n"
|
||||
" } else\n"
|
||||
" return counter;\n"
|
||||
" \n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:7]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead.\n", errout.str());
|
||||
|
||||
checkInterlockedDecrement(
|
||||
"int f() {\n"
|
||||
" int counter = 0;\n"
|
||||
" if (::InterlockedDecrement(&counter) == 0) {\n"
|
||||
" destroy();\n"
|
||||
" return 0;\n"
|
||||
" } else\n"
|
||||
" return counter;\n"
|
||||
" \n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("[test.cpp:7]: (error) Race condition: non-interlocked access after InterlockedDecrement(). Use InterlockedDecrement() return value instead.\n", errout.str());
|
||||
}
|
||||
|
||||
void testUnusedLabel() {
|
||||
|
|
Loading…
Reference in New Issue