Fix ValueType for references in range-based for loop (#4116)

* Fix ValueType for references in range-based for loop

* Format
This commit is contained in:
chrchr-github 2022-05-20 08:48:01 +02:00 committed by GitHub
parent 112b1573c5
commit 2b723eafcb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 14 additions and 4 deletions

View File

@ -6139,7 +6139,7 @@ void SymbolDatabase::setValueType(Token *tok, const ValueType &valuetype)
// range for loop, auto
if (vt2 &&
parent->str() == ":" &&
Token::Match(parent->astParent(), "( const| auto *|&| %var% :") &&
Token::Match(parent->astParent(), "( const| auto *|&| %var% :") && // TODO: east-const, multiple const, ref to ptr, rvalue ref
!parent->previous()->valueType() &&
Token::simpleMatch(parent->astParent()->astOperand1(), "for")) {
const bool isconst = Token::simpleMatch(parent->astParent()->next(), "const");
@ -6152,8 +6152,14 @@ void SymbolDatabase::setValueType(Token *tok, const ValueType &valuetype)
setAutoTokenProperties(autoToken);
ValueType varvt(*vt2);
varvt.pointer--;
if (isconst)
varvt.constness |= 1;
if (Token::simpleMatch(autoToken->next(), "&"))
varvt.reference = Reference::LValue;
if (isconst) {
if (varvt.pointer && varvt.reference != Reference::None)
varvt.constness |= 2;
else
varvt.constness |= 1;
}
setValueType(parent->previous(), varvt);
Variable *var = const_cast<Variable *>(parent->previous()->variable());
if (var) {

View File

@ -7736,7 +7736,11 @@ private:
ASSERT_EQUALS("signed int", typeOf("; auto data = new X::Y; int x=1000; x=x/5;", "/")); // #7970
ASSERT_EQUALS("signed int *", typeOf("; auto data = new (nothrow) int[100];", "data"));
ASSERT_EQUALS("signed int *", typeOf("; auto data = new (std::nothrow) int[100];", "data"));
ASSERT_EQUALS("const signed short", typeOf("short values[10]; void f() { for (const auto *x : values); }", "x"));
ASSERT_EQUALS("const signed short", typeOf("short values[10]; void f() { for (const auto x : values); }", "x"));
ASSERT_EQUALS("const signed short &", typeOf("short values[10]; void f() { for (const auto& x : values); }", "x"));
ASSERT_EQUALS("signed short &", typeOf("short values[10]; void f() { for (auto& x : values); }", "x"));
ASSERT_EQUALS("signed int * &", typeOf("int* values[10]; void f() { for (auto& p : values); }", "p"));
ASSERT_EQUALS("signed int * const &", typeOf("int* values[10]; void f() { for (const auto& p : values); }", "p"));
ASSERT_EQUALS("const signed int", typeOf("; const auto x = 3;", "x"));
ASSERT_EQUALS("const signed int", typeOf("; constexpr auto x = 3;", "x"));
ASSERT_EQUALS("const signed int", typeOf("; const constexpr auto x = 3;", "x"));