From 91e73c39b7138a8b8281693c2cf0d4e1a6cbc82d Mon Sep 17 00:00:00 2001 From: chrchr Date: Fri, 24 Feb 2023 17:52:03 +0100 Subject: [PATCH 1/8] Get type from auto with scope --- lib/token.cpp | 9 ++++++++- test/testfunctions.cpp | 9 +++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/token.cpp b/lib/token.cpp index 40be28382b8..d2fe45e4ad7 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -2264,9 +2264,16 @@ std::pair Token::typeDecl(const Token* tok, bool poi tok2 = tok2->tokAt(2); if (Token::simpleMatch(tok2, "=") && Token::Match(tok2->astOperand2(), "!!=") && tok != tok2->astOperand2()) { tok2 = tok2->astOperand2(); - std::pair r = typeDecl(tok2); + + const Token* varTok = tok2; // try to find a variable + if (Token::Match(varTok, ":: %name%")) + varTok = varTok->next(); + while (Token::Match(varTok, "%name% ::")) + varTok = varTok->tokAt(2); + std::pair r = typeDecl(varTok); if (r.first) return r; + if (pointedToType && tok2->astOperand1() && Token::simpleMatch(tok2, "new")) { if (Token::simpleMatch(tok2->astOperand1(), "(")) return { tok2->next(), tok2->astOperand1() }; diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp index 937d2c57fb2..50648588b10 100644 --- a/test/testfunctions.cpp +++ b/test/testfunctions.cpp @@ -1966,6 +1966,15 @@ class TestFunctions : public TestFixture { "}\n"); ASSERT_EQUALS("", errout.str()); + check("namespace N {\n" + " struct S { static const std::set s; };\n" + "}\n" + "void f() {\n" + " const auto& t = N::S::s;\n" + " if (t.find(\"abc\") != t.end()) {}\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + settings = settings_old; } From ee288e0e40e179b1ef0fa4bcc70eb9256f6024dd Mon Sep 17 00:00:00 2001 From: chrchr Date: Fri, 24 Feb 2023 17:52:37 +0100 Subject: [PATCH 2/8] Useless cast --- lib/symboldatabase.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index eb1861d6e22..9e216a3556b 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -972,7 +972,7 @@ void SymbolDatabase::createSymbolDatabaseVariableSymbolTable() { // create variable symbol table mVariableList.resize(mTokenizer->varIdCount() + 1); - std::fill_n(mVariableList.begin(), mVariableList.size(), (const Variable*)nullptr); + std::fill_n(mVariableList.begin(), mVariableList.size(), nullptr); // check all scopes for variables for (Scope& scope : scopeList) { From 891667a00e28377c13df26bb5acf06927ce4b8e9 Mon Sep 17 00:00:00 2001 From: chrchr Date: Fri, 24 Feb 2023 17:53:42 +0100 Subject: [PATCH 3/8] Use find() with offset --- lib/templatesimplifier.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 45a5328426a..4a3b0f95edb 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -965,7 +965,7 @@ void TemplateSimplifier::getTemplateInstantiations() // insert using namespace into token stream std::string::size_type offset = 0; std::string::size_type pos = 0; - while ((pos = nameSpace.substr(offset).find(' ')) != std::string::npos) { + while ((pos = nameSpace.find(' ', offset)) != std::string::npos) { qualificationTok->insertToken(nameSpace.substr(offset, pos), emptyString, true); offset = offset + pos + 1; } From 11044bcf441109a9819ef5bcb01a4fa6e57a8229 Mon Sep 17 00:00:00 2001 From: chrchr Date: Fri, 24 Feb 2023 18:17:01 +0100 Subject: [PATCH 4/8] Fix indices --- lib/templatesimplifier.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 4a3b0f95edb..922411325ff 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -966,8 +966,8 @@ void TemplateSimplifier::getTemplateInstantiations() std::string::size_type offset = 0; std::string::size_type pos = 0; while ((pos = nameSpace.find(' ', offset)) != std::string::npos) { - qualificationTok->insertToken(nameSpace.substr(offset, pos), emptyString, true); - offset = offset + pos + 1; + qualificationTok->insertToken(nameSpace.substr(offset, pos - offset), emptyString, true); + offset = pos + 1; } qualificationTok->insertToken(nameSpace.substr(offset), emptyString, true); qualificationTok->insertToken("::", emptyString, true); From 03fd7680ef912244b56914a3d81a0a3a01c4f23e Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Fri, 24 Feb 2023 23:32:48 +0100 Subject: [PATCH 5/8] Get type from auto with index operator --- lib/token.cpp | 2 ++ test/testfunctions.cpp | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/lib/token.cpp b/lib/token.cpp index d2fe45e4ad7..fcf5de7fa37 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -2270,6 +2270,8 @@ std::pair Token::typeDecl(const Token* tok, bool poi varTok = varTok->next(); while (Token::Match(varTok, "%name% ::")) varTok = varTok->tokAt(2); + while (Token::simpleMatch(varTok, "[")) + varTok = varTok->astOperand1(); std::pair r = typeDecl(varTok); if (r.first) return r; diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp index 50648588b10..10377d7171a 100644 --- a/test/testfunctions.cpp +++ b/test/testfunctions.cpp @@ -1975,6 +1975,12 @@ class TestFunctions : public TestFixture { "}\n"); ASSERT_EQUALS("", errout.str()); + check("void f(std::vector>>& v, int i, int j) {\n" + " auto& s = v[i][j];\n" + " s.insert(0);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + settings = settings_old; } From 4b50d0f6db8de45df6d85ff1f67d42b952157106 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Sat, 25 Feb 2023 22:40:22 +0100 Subject: [PATCH 6/8] Fix function lookup --- lib/token.cpp | 8 ++++++-- test/testfunctions.cpp | 12 ++++++++++++ test/testsymboldatabase.cpp | 34 ++++++++++++++++++++++++---------- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/lib/token.cpp b/lib/token.cpp index fcf5de7fa37..f4881ad5972 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -2265,13 +2265,17 @@ std::pair Token::typeDecl(const Token* tok, bool poi if (Token::simpleMatch(tok2, "=") && Token::Match(tok2->astOperand2(), "!!=") && tok != tok2->astOperand2()) { tok2 = tok2->astOperand2(); + if (Token::simpleMatch(tok2, "[") && tok2->astOperand1()) { + const ValueType* vt = tok2->astOperand1()->valueType(); + if (vt && vt->containerTypeToken) + return { vt->containerTypeToken, vt->containerTypeToken->linkAt(-1) }; + } + const Token* varTok = tok2; // try to find a variable if (Token::Match(varTok, ":: %name%")) varTok = varTok->next(); while (Token::Match(varTok, "%name% ::")) varTok = varTok->tokAt(2); - while (Token::simpleMatch(varTok, "[")) - varTok = varTok->astOperand1(); std::pair r = typeDecl(varTok); if (r.first) return r; diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp index 10377d7171a..f3f62b7ba9e 100644 --- a/test/testfunctions.cpp +++ b/test/testfunctions.cpp @@ -1981,6 +1981,18 @@ class TestFunctions : public TestFixture { "}\n"); ASSERT_EQUALS("", errout.str()); + check("void f(std::vector>>& v, int i, int j) {\n" + " auto& s = v[i][j];\n" + " s.insert(0);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("int f(const std::vector&v, int i, char c) {\n" + " const auto& s = v[i];\n" + " return s.find(c);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + settings = settings_old; } diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 2d79649a76f..23c6862938b 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -481,6 +481,7 @@ class TestSymbolDatabase : public TestFixture { TEST_CASE(valueType1); TEST_CASE(valueType2); + TEST_CASE(valueType3); TEST_CASE(valueTypeThis); TEST_CASE(variadic1); // #7453 @@ -8074,16 +8075,16 @@ class TestSymbolDatabase : public TestFixture { void valueType2() { GET_SYMBOL_DB("int i;\n" - "bool b;\n" - "Unknown u;\n" - "std::string s;\n" - "std::vector v;\n" - "std::map::const_iterator it;\n" - "void* p;\n" - "\n" - "void f() {\n" - " func(i, b, u, s, v, it, p);\n" - "}"); + "bool b;\n" + "Unknown u;\n" + "std::string s;\n" + "std::vector v;\n" + "std::map::const_iterator it;\n" + "void* p;\n" + "\n" + "void f() {\n" + " func(i, b, u, s, v, it, p);\n" + "}"); const Token* tok = tokenizer.tokens(); @@ -8115,6 +8116,19 @@ class TestSymbolDatabase : public TestFixture { } } + void valueType3() { + GET_SYMBOL_DB("void f(std::vector>>& v, int i, int j) {\n" + " auto& s = v[i][j];\n" + " s.insert(0);\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + const Token* tok = tokenizer.tokens(); + tok = Token::findsimplematch(tok, "s ."); + ASSERT(tok && tok->valueType()); + ASSERT_EQUALS("container(std :: set|unordered_set <)", tok->valueType()->str()); + } + void valueTypeThis() { ASSERT_EQUALS("C *", typeOf("class C { C() { *this = 0; } };", "this")); ASSERT_EQUALS("const C *", typeOf("class C { void foo() const; }; void C::foo() const { *this = 0; }", "this")); From da5d64f02adcd494bcced97272a8c27183456dfa Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Sat, 25 Feb 2023 22:44:22 +0100 Subject: [PATCH 7/8] Remove duplicate --- test/testfunctions.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/test/testfunctions.cpp b/test/testfunctions.cpp index f3f62b7ba9e..dfc82624adc 100644 --- a/test/testfunctions.cpp +++ b/test/testfunctions.cpp @@ -1981,13 +1981,7 @@ class TestFunctions : public TestFixture { "}\n"); ASSERT_EQUALS("", errout.str()); - check("void f(std::vector>>& v, int i, int j) {\n" - " auto& s = v[i][j];\n" - " s.insert(0);\n" - "}\n"); - ASSERT_EQUALS("", errout.str()); - - check("int f(const std::vector&v, int i, char c) {\n" + check("int f(const std::vector& v, int i, char c) {\n" " const auto& s = v[i];\n" " return s.find(c);\n" "}\n"); From 4a76c7ccb4287be010d58e18bb43113a346e7016 Mon Sep 17 00:00:00 2001 From: chrchr-github Date: Sat, 25 Feb 2023 22:45:36 +0100 Subject: [PATCH 8/8] Format --- test/testsymboldatabase.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 23c6862938b..a6631f05331 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -8075,16 +8075,16 @@ class TestSymbolDatabase : public TestFixture { void valueType2() { GET_SYMBOL_DB("int i;\n" - "bool b;\n" - "Unknown u;\n" - "std::string s;\n" - "std::vector v;\n" - "std::map::const_iterator it;\n" - "void* p;\n" - "\n" - "void f() {\n" - " func(i, b, u, s, v, it, p);\n" - "}"); + "bool b;\n" + "Unknown u;\n" + "std::string s;\n" + "std::vector v;\n" + "std::map::const_iterator it;\n" + "void* p;\n" + "\n" + "void f() {\n" + " func(i, b, u, s, v, it, p);\n" + "}"); const Token* tok = tokenizer.tokens();