Skip to content

Commit 405edfd

Browse files
authored
fix #13977: false negative: unreadVariable with unrelated function call after rvalue declaration (regression) (danmar#7702)
1 parent cc18720 commit 405edfd

File tree

4 files changed

+21
-7
lines changed

4 files changed

+21
-7
lines changed

lib/fwdanalysis.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ static bool hasGccCompoundStatement(const Token *tok)
7676

7777
static bool nonLocal(const Variable* var, bool deref)
7878
{
79-
return !var || (!var->isLocal() && !var->isArgument()) || (deref && var->isArgument() && var->isPointer()) || var->isStatic() || var->isReference() || var->isExtern();
79+
return !var || (!var->isLocal() && !var->isArgument()) || (deref && var->isArgument() && var->isPointer()) || var->isStatic() || var->isExtern();
8080
}
8181

8282
static bool hasVolatileCastOrVar(const Token *expr)

lib/tokenlist.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1762,10 +1762,10 @@ static Token * createAstAtToken(Token *tok)
17621762
}
17631763
}
17641764

1765-
if (Token::Match(tok, "%type% %name%|*|&|::") && !Token::Match(tok, "return|new|delete")) {
1765+
if (Token::Match(tok, "%type% %name%|*|&|&&|::") && !Token::Match(tok, "return|new|delete")) {
17661766
int typecount = 0;
17671767
Token *typetok = tok;
1768-
while (Token::Match(typetok, "%type%|::|*|&")) {
1768+
while (Token::Match(typetok, "%type%|::|*|&|&&")) {
17691769
if (typetok->isName() && !Token::simpleMatch(typetok->previous(), "::"))
17701770
typecount++;
17711771
typetok = typetok->next();

test/testtokenize.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,7 @@ class TestTokenizer : public TestFixture {
404404
TEST_CASE(astnewscoped);
405405
TEST_CASE(astdecltypescope);
406406
TEST_CASE(astdesignatedinit);
407+
TEST_CASE(astrvaluedecl);
407408

408409
TEST_CASE(startOfExecutableScope);
409410

@@ -7181,6 +7182,10 @@ class TestTokenizer : public TestFixture {
71817182
ASSERT_EQUALS("(( f ({ (= (. x) 1)))", testAst("f({ .x = 1 });", AstStyle::Z3));
71827183
}
71837184

7185+
void astrvaluedecl() {
7186+
ASSERT_EQUALS("varstdmove::var(=", testAst("std::string&& var = std::move(var);"));
7187+
}
7188+
71847189
#define isStartOfExecutableScope(offset, code) isStartOfExecutableScope_(offset, code, __FILE__, __LINE__)
71857190
template<size_t size>
71867191
bool isStartOfExecutableScope_(int offset, const char (&code)[size], const char* file, int line) {

test/testunusedvar.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,7 @@ class TestUnusedVar : public TestFixture {
188188
TEST_CASE(localvarconst2);
189189
TEST_CASE(localvarreturn); // ticket #9167
190190
TEST_CASE(localvarmaybeunused);
191+
TEST_CASE(localvarrvalue); // ticket #13977
191192

192193
TEST_CASE(localvarthrow); // ticket #3687
193194

@@ -5200,10 +5201,9 @@ class TestUnusedVar : public TestFixture {
52005201
" const auto&& c = g();\n"
52015202
" auto&& d = c;\n"
52025203
"}\n");
5203-
TODO_ASSERT_EQUALS("[test.cpp:5:20]: (style) Variable 'b' is assigned a value that is never used.\n"
5204-
"[test.cpp:7:14]: (style) Variable 'd' is assigned a value that is never used. [unreadVariable]\n",
5205-
"[test.cpp:7:14]: (style) Variable 'd' is assigned a value that is never used. [unreadVariable]\n",
5206-
errout_str());
5204+
ASSERT_EQUALS("[test.cpp:5:19]: (style) Variable 'b' is assigned a value that is never used. [unreadVariable]\n"
5205+
"[test.cpp:7:14]: (style) Variable 'd' is assigned a value that is never used. [unreadVariable]\n",
5206+
errout_str());
52075207
}
52085208

52095209
void localvaralias21() { // #11728
@@ -6473,6 +6473,15 @@ class TestUnusedVar : public TestFixture {
64736473
ASSERT_EQUALS("", errout_str());
64746474
}
64756475

6476+
void localvarrvalue() { // ticket #13977
6477+
functionVariableUsage("void f(void) {\n"
6478+
" std::string s;\n"
6479+
" std::string&& m = std::move(s);\n"
6480+
" cb();\n"
6481+
"}\n");
6482+
ASSERT_EQUALS("[test.cpp:3:21]: (style) Variable 'm' is assigned a value that is never used. [unreadVariable]\n", errout_str());
6483+
}
6484+
64766485
void localvarthrow() { // ticket #3687
64776486
functionVariableUsage("void foo() {\n"
64786487
" try {}"

0 commit comments

Comments
 (0)