Skip to content

Commit 4ef0318

Browse files
Fix #11895 FP derefInvalidIterator with std::advance (#8431)
Needs to be rebased after #8423 has been merged. --------- Co-authored-by: chrchr-github <noreply@github.com>
1 parent e946e50 commit 4ef0318

6 files changed

Lines changed: 16 additions & 28 deletions

File tree

cfg/selinux.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@
219219
<noreturn>false</noreturn>
220220
<use-retval/>
221221
<leak-ignore/>
222-
<arg nr="1" direction="inout">
222+
<arg nr="1" direction="inout" indirect="1">
223223
<not-uninit/>
224224
<not-null/>
225225
</arg>

cfg/std.cfg

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1665,7 +1665,7 @@
16651665
<returnValue type="int"/>
16661666
<noreturn>false</noreturn>
16671667
<leak-ignore/>
1668-
<arg nr="1" direction="inout">
1668+
<arg nr="1" direction="inout" indirect="1">
16691669
<not-null/>
16701670
<not-uninit/>
16711671
</arg>
@@ -1929,7 +1929,7 @@
19291929
<returnValue type="int"/>
19301930
<noreturn>false</noreturn>
19311931
<leak-ignore/>
1932-
<arg nr="1" direction="inout">
1932+
<arg nr="1" direction="inout" indirect="1">
19331933
<not-null/>
19341934
<not-uninit/>
19351935
</arg>
@@ -2255,7 +2255,7 @@
22552255
<returnValue type="int"/>
22562256
<noreturn>false</noreturn>
22572257
<leak-ignore/>
2258-
<arg nr="1" direction="inout">
2258+
<arg nr="1" direction="inout" indirect="1">
22592259
<not-null/>
22602260
<not-uninit/>
22612261
</arg>

cfg/windows.cfg

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5595,7 +5595,7 @@ HFONT CreateFont(
55955595
<function name="strlwr">
55965596
<returnValue type="char *">arg1</returnValue>
55975597
<noreturn>false</noreturn>
5598-
<arg nr="1" direction="inout">
5598+
<arg nr="1" direction="inout" indirect="1">
55995599
<not-null/>
56005600
<not-uninit/>
56015601
<strz/>
@@ -5963,7 +5963,7 @@ HFONT CreateFont(
59635963
<arg nr="2" direction="out">
59645964
<not-null/>
59655965
</arg>
5966-
<arg nr="3" direction="inout">
5966+
<arg nr="3" direction="inout" indirect="1">
59675967
<not-null/>
59685968
<not-uninit/>
59695969
</arg>
@@ -6009,7 +6009,7 @@ HFONT CreateFont(
60096009
<arg nr="4" direction="out">
60106010
<not-null/>
60116011
</arg>
6012-
<arg nr="5" direction="inout">
6012+
<arg nr="5" direction="inout" indirect="1">
60136013
<not-null/>
60146014
<not-uninit/>
60156015
</arg>

lib/astutils.cpp

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2466,17 +2466,6 @@ static bool isTrivialConstructor(const Token* tok)
24662466
return false;
24672467
}
24682468

2469-
static bool isArray(const Token* tok)
2470-
{
2471-
if (!tok)
2472-
return false;
2473-
if (tok->variable())
2474-
return tok->variable()->isArray();
2475-
if (Token::simpleMatch(tok, "."))
2476-
return isArray(tok->astOperand2());
2477-
return false;
2478-
}
2479-
24802469
bool isMutableExpression(const Token* tok)
24812470
{
24822471
if (!tok)
@@ -2545,18 +2534,10 @@ bool isVariableChangedByFunctionCall(const Token *tok, int indirect, const Setti
25452534
const Library::ArgumentChecks::Direction argDirection = settings.library.getArgDirection(tok, 1 + argnr, indirect);
25462535
if (argDirection == Library::ArgumentChecks::Direction::DIR_IN)
25472536
return false;
2548-
if (argDirection == Library::ArgumentChecks::Direction::DIR_OUT)
2537+
if (argDirection == Library::ArgumentChecks::Direction::DIR_OUT || argDirection == Library::ArgumentChecks::Direction::DIR_INOUT)
25492538
return true;
25502539

25512540
const bool requireNonNull = settings.library.isnullargbad(tok, 1 + argnr);
2552-
if (argDirection == Library::ArgumentChecks::Direction::DIR_INOUT) {
2553-
if (indirect == 0 && isArray(tok1))
2554-
return true;
2555-
const bool requireInit = settings.library.isuninitargbad(tok, 1 + argnr);
2556-
// Assume that if the variable must be initialized then the indirection is 1
2557-
if (indirect > 0 && requireInit && requireNonNull)
2558-
return true;
2559-
}
25602541
if (Token::simpleMatch(tok->tokAt(-2), "std :: tie"))
25612542
return true;
25622543
// if the library says 0 is invalid

lib/checkvaarg.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ void CheckVaarg::va_start_argument()
7373
if (var && var->index() + 2 < function->argCount() && printWarnings) {
7474
auto it = function->argumentList.end();
7575
std::advance(it, -2);
76-
wrongParameterTo_va_start_error(tok, var->name(), it->name()); // cppcheck-suppress derefInvalidIterator // FP due to isVariableChangedByFunctionCall()
76+
wrongParameterTo_va_start_error(tok, var->name(), it->name());
7777
}
7878
tok = tok->linkAt(1);
7979
}

test/teststl.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5339,6 +5339,13 @@ class TestStl : public TestFixture {
53395339
" return it;\n"
53405340
"}\n", dinit(CheckOptions, $.inconclusive = true));
53415341
ASSERT_EQUALS("[test.cpp:18:5]: (error, inconclusive) Invalid iterator 'it' used. [eraseDereference]\n", errout_str());
5342+
5343+
check("int f(const std::vector<int>& v) {\n" // #11895
5344+
" auto it = v.end();\n"
5345+
" std::advance(it, -2);\n"
5346+
" return *it;\n"
5347+
"}\n", dinit(CheckOptions, $.inconclusive = true));
5348+
ASSERT_EQUALS("", errout_str());
53425349
}
53435350

53445351
void loopAlgoElementAssign() {

0 commit comments

Comments
 (0)