Fix #11473 FP constVariable / #11448 FP constParameter / #11188 FP danglingTempReference (#4680)

* Fix #11473 FP constVariable with range-based for / #11448 FP constParameter with unused non-const range loop variable

* Fix ValueType / #11188 FP danglingTempReference with auto

* Fix ValueType in range-based for

* Update symboldatabase.cpp
This commit is contained in:
chrchr-github 2023-01-11 22:04:06 +01:00 committed by GitHub
parent a77f0d9403
commit 7bbdc95f25
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 62 additions and 8 deletions

View File

@ -1464,6 +1464,13 @@ void CheckOther::checkConstVariable()
break; break;
} }
} }
if (astIsRangeBasedForDecl(tok) && Token::Match(tok->astParent()->astOperand2(), "%varid%", var->declarationId())) {
const Variable* refvar = tok->astParent()->astOperand1()->variable();
if (refvar && refvar->isReference() && !refvar->isConst()) {
usedInAssignment = true;
break;
}
}
} }
if (usedInAssignment) if (usedInAssignment)
continue; continue;

View File

@ -6132,7 +6132,7 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
if (autoTok->strAt(1) == "*" && vt.pointer) if (autoTok->strAt(1) == "*" && vt.pointer)
vt.pointer--; vt.pointer--;
if (Token::Match(autoTok->tokAt(-1), "const|constexpr")) if (Token::Match(autoTok->tokAt(-1), "const|constexpr"))
vt.constness |= 1; vt.constness |= (1 << vt.pointer);
setValueType(autoTok, vt); setValueType(autoTok, vt);
setAutoTokenProperties(autoTok); setAutoTokenProperties(autoTok);
if (vt2->pointer > vt.pointer) if (vt2->pointer > vt.pointer)
@ -6338,8 +6338,10 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
setValueType(autoToken, autovt); setValueType(autoToken, autovt);
setAutoTokenProperties(autoToken); setAutoTokenProperties(autoToken);
ValueType varvt(autovt); ValueType varvt(autovt);
if (autoToken->strAt(1) == "*" && autovt.pointer)
autovt.pointer--;
if (isconst) if (isconst)
varvt.constness |= 1; varvt.constness |= (1 << autovt.pointer);
setValueType(parent->previous(), varvt); setValueType(parent->previous(), varvt);
Variable * var = const_cast<Variable *>(parent->previous()->variable()); Variable * var = const_cast<Variable *>(parent->previous()->variable());
if (var) { if (var) {

View File

@ -2022,6 +2022,13 @@ private:
" const int& x = (*e)[1];\n" " const int& x = (*e)[1];\n"
"}\n"); "}\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("int* g();\n" // #11188
"void f() {\n"
" const auto& p = g();\n"
" if (p != nullptr) {}\n"
"}\n");
ASSERT_EQUALS("", errout.str());
} }
void testglobalnamespace() { void testglobalnamespace() {

View File

@ -2349,8 +2349,7 @@ private:
check("void f(std::vector<int>& v) {\n" check("void f(std::vector<int>& v) {\n"
" for(auto& x:v) {}\n" " for(auto& x:v) {}\n"
"}"); "}");
ASSERT_EQUALS("[test.cpp:1]: (style) Parameter 'v' can be declared as reference to const\n" ASSERT_EQUALS("[test.cpp:2]: (style) Variable 'x' can be declared as reference to const\n",
"[test.cpp:2]: (style) Variable 'x' can be declared as reference to const\n",
errout.str()); errout.str());
check("void f(std::vector<int>& v) {\n" // #10980 check("void f(std::vector<int>& v) {\n" // #10980
@ -3019,6 +3018,16 @@ private:
" std::cout << m[0] << std::endl;\n" " std::cout << m[0] << std::endl;\n"
"};\n"); "};\n");
ASSERT_EQUALS("", errout.str()); ASSERT_EQUALS("", errout.str());
check("struct S { int i; };\n" // #11473
"void f(std::vector<std::vector<S>>&m, int*& p) {\n"
" auto& a = m[0];\n"
" for (auto& s : a) {\n"
" p = &s.i;\n"
" return;\n"
" }\n"
"}\n");
ASSERT_EQUALS("", errout.str());
} }
void constParameterCallback() { void constParameterCallback() {

View File

@ -500,6 +500,7 @@ private:
TEST_CASE(auto15); // C++17 auto deduction from braced-init-list TEST_CASE(auto15); // C++17 auto deduction from braced-init-list
TEST_CASE(auto16); TEST_CASE(auto16);
TEST_CASE(auto17); // #11163 TEST_CASE(auto17); // #11163
TEST_CASE(auto18);
TEST_CASE(unionWithConstructor); TEST_CASE(unionWithConstructor);
@ -8469,14 +8470,14 @@ private:
autotok = Token::findsimplematch(autotok, "auto v4"); autotok = Token::findsimplematch(autotok, "auto v4");
ASSERT(autotok); ASSERT(autotok);
ASSERT(autotok->valueType()); ASSERT(autotok->valueType());
TODO_ASSERT_EQUALS(0, 1, autotok->valueType()->constness); ASSERT_EQUALS(3, autotok->valueType()->constness);
ASSERT_EQUALS(1, autotok->valueType()->pointer); ASSERT_EQUALS(1, autotok->valueType()->pointer);
ASSERT_EQUALS(ValueType::SIGNED, autotok->valueType()->sign); ASSERT_EQUALS(ValueType::SIGNED, autotok->valueType()->sign);
ASSERT_EQUALS(ValueType::INT, autotok->valueType()->type); ASSERT_EQUALS(ValueType::INT, autotok->valueType()->type);
vartok = Token::findsimplematch(autotok, "v4 ="); vartok = Token::findsimplematch(autotok, "v4 =");
ASSERT(autotok); ASSERT(autotok);
ASSERT(autotok->valueType()); ASSERT(autotok->valueType());
ASSERT_EQUALS(1, vartok->valueType()->constness); ASSERT_EQUALS(3, vartok->valueType()->constness);
ASSERT_EQUALS(1, vartok->valueType()->pointer); ASSERT_EQUALS(1, vartok->valueType()->pointer);
ASSERT_EQUALS(ValueType::SIGNED, vartok->valueType()->sign); ASSERT_EQUALS(ValueType::SIGNED, vartok->valueType()->sign);
ASSERT_EQUALS(ValueType::INT, vartok->valueType()->type); ASSERT_EQUALS(ValueType::INT, vartok->valueType()->type);
@ -8549,14 +8550,14 @@ private:
autotok = Token::findsimplematch(autotok, "auto v9"); autotok = Token::findsimplematch(autotok, "auto v9");
ASSERT(autotok); ASSERT(autotok);
ASSERT(autotok->valueType()); ASSERT(autotok->valueType());
TODO_ASSERT_EQUALS(0, 1, autotok->valueType()->constness); ASSERT_EQUALS(3, autotok->valueType()->constness);
ASSERT_EQUALS(1, autotok->valueType()->pointer); ASSERT_EQUALS(1, autotok->valueType()->pointer);
ASSERT_EQUALS(ValueType::SIGNED, autotok->valueType()->sign); ASSERT_EQUALS(ValueType::SIGNED, autotok->valueType()->sign);
ASSERT_EQUALS(ValueType::INT, autotok->valueType()->type); ASSERT_EQUALS(ValueType::INT, autotok->valueType()->type);
vartok = Token::findsimplematch(autotok, "v9 ="); vartok = Token::findsimplematch(autotok, "v9 =");
ASSERT(autotok); ASSERT(autotok);
ASSERT(autotok->valueType()); ASSERT(autotok->valueType());
ASSERT_EQUALS(1, vartok->valueType()->constness); ASSERT_EQUALS(3, vartok->valueType()->constness);
ASSERT_EQUALS(1, vartok->valueType()->pointer); ASSERT_EQUALS(1, vartok->valueType()->pointer);
ASSERT_EQUALS(ValueType::SIGNED, vartok->valueType()->sign); ASSERT_EQUALS(ValueType::SIGNED, vartok->valueType()->sign);
ASSERT_EQUALS(ValueType::INT, vartok->valueType()->type); ASSERT_EQUALS(ValueType::INT, vartok->valueType()->type);
@ -8750,6 +8751,34 @@ private:
ASSERT_EQUALS(5, db->variableList().size()); ASSERT_EQUALS(5, db->variableList().size());
} }
void auto18() {
GET_SYMBOL_DB("void f(const int* p) {\n"
" const int* const& r = p;\n"
" const auto& s = p;\n"
"}\n");
ASSERT_EQUALS(4, db->variableList().size());
const Variable* r = db->variableList()[2];
ASSERT(r->isReference());
ASSERT(r->isConst());
ASSERT(r->isPointer());
const Token* varTok = Token::findsimplematch(tokenizer.tokens(), "r");
ASSERT(varTok && varTok->valueType());
ASSERT_EQUALS(varTok->valueType()->constness, 3);
ASSERT_EQUALS(varTok->valueType()->pointer, 1);
ASSERT(varTok->valueType()->reference == Reference::LValue);
const Variable* s = db->variableList()[3];
ASSERT(s->isReference());
ASSERT(s->isConst());
ASSERT(s->isPointer());
const Token* autoTok = Token::findsimplematch(tokenizer.tokens(), "auto");
ASSERT(autoTok && autoTok->valueType());
ASSERT_EQUALS(autoTok->valueType()->constness, 3);
ASSERT_EQUALS(autoTok->valueType()->pointer, 1);
TODO_ASSERT(autoTok->valueType()->reference == Reference::LValue);
}
void unionWithConstructor() { void unionWithConstructor() {
GET_SYMBOL_DB("union Fred {\n" GET_SYMBOL_DB("union Fred {\n"
" Fred(int x) : i(x) { }\n" " Fred(int x) : i(x) { }\n"