diff --git a/lib/checkother.cpp b/lib/checkother.cpp index 745fbdf43..7e5f56136 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1549,11 +1549,13 @@ void CheckOther::checkConstPointer() continue; const Token* const nameTok = tok->variable()->nameToken(); // declarations of (static) pointers are (not) split up, array declarations are never split up - if (tok == nameTok && (!Token::simpleMatch(tok->variable()->typeStartToken()->previous(), "static") || Token::simpleMatch(nameTok->next(), "["))) + if (tok == nameTok && (!tok->variable()->isStatic() || Token::simpleMatch(nameTok->next(), "[")) && + // range-based for loop + !(Token::simpleMatch(nameTok->astParent(), ":") && Token::simpleMatch(nameTok->astParent()->astParent(), "("))) continue; if (!tok->valueType()) continue; - if (tok->valueType()->pointer == 0 || tok->valueType()->constness > 0) + if (tok->valueType()->pointer == 0 || (tok->valueType()->constness & 1)) continue; if (nonConstPointers.find(tok->variable()) != nonConstPointers.end()) continue; diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index a0e4e5950..994513c09 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -6150,7 +6150,7 @@ void SymbolDatabase::setValueType(Token *tok, const ValueType &valuetype) setAutoTokenProperties(autoToken); ValueType varvt(autovt); if (isconst) - varvt.constness |= 1; + varvt.constness |= (1 << varvt.pointer); setValueType(parent->previous(), varvt); Variable * var = const_cast(parent->previous()->variable()); if (var) { diff --git a/test/testother.cpp b/test/testother.cpp index 93533a7e4..9ed594519 100644 --- a/test/testother.cpp +++ b/test/testother.cpp @@ -2997,6 +2997,44 @@ private: " if (i[0] == 0) {}\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + // #10466 + check("void f(const std::vector& v) {\n" + " for (const auto& p : v)\n" + " if (p == nullptr) {}\n" + " for (const auto* p : v)\n" + " if (p == nullptr) {}\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("void f(std::vector& v) {\n" + " for (const auto& p : v)\n" + " if (p == nullptr) {}\n" + " for (const auto* p : v)\n" + " if (p == nullptr) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'v' can be declared with const\n", errout.str()); + + check("void f(std::vector& v) {\n" + " for (const auto& p : v)\n" + " if (p == nullptr) {}\n" + " for (const auto* p : v)\n" + " if (p == nullptr) {}\n" + "}\n"); + ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'v' can be declared with const\n", errout.str()); + + check("void f(const std::vector& v) {\n" + " for (const auto& p : v)\n" + " if (p == nullptr) {}\n" + " for (const auto* p : v)\n" + " if (p == nullptr) {}\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); + + check("void f(const int* const p) {\n" + " if (p == nullptr) {}\n" + "}\n"); + ASSERT_EQUALS("", errout.str()); } void switchRedundantAssignmentTest() { @@ -9112,7 +9150,7 @@ private: " int local_argc = 0;\n" " local_argv[local_argc++] = argv[0];\n" "}\n", "test.c"); - ASSERT_EQUALS("", errout.str()); + ASSERT_EQUALS("[test.c:1]: (style) Parameter 'argv' can be declared with const\n", errout.str()); check("void f() {\n" " int x = 0;\n"