Merge pull request #711 from Dmitry-Me/moreInterlockedCases
Detect more non-interlocked accesses
This commit is contained in:
commit
423b254772
|
@ -2418,6 +2418,24 @@ void CheckOther::checkInterlockedDecrement()
|
||||||
(Token::Match(checkStartTok, "%name% %comp% 0 )") && checkStartTok->str() == interlockedVarTok->str())) {
|
(Token::Match(checkStartTok, "%name% %comp% 0 )") && checkStartTok->str() == interlockedVarTok->str())) {
|
||||||
raceAfterInterlockedDecrementError(checkStartTok);
|
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"
|
" destroy;\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
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() {
|
void testUnusedLabel() {
|
||||||
|
|
Loading…
Reference in New Issue