Skip to content

Commit 1444cd8

Browse files
authored
Fix #14782: Partially or fully missing valuetype info for auto declarations (#8599)
1 parent b6e1f45 commit 1444cd8

2 files changed

Lines changed: 120 additions & 9 deletions

File tree

lib/symboldatabase.cpp

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7021,6 +7021,10 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, const
70217021
setAutoTokenProperties(autoTok);
70227022
if (vt2->pointer > vt.pointer)
70237023
vt.pointer++;
7024+
if (Token::simpleMatch(autoTok->next(), "&"))
7025+
vt.reference = Reference::LValue;
7026+
if (Token::simpleMatch(autoTok->next(), "&&"))
7027+
vt.reference = Reference::RValue;
70247028
setValueType(var1Tok, vt);
70257029
if (var1Tok != parent->previous())
70267030
setValueType(parent->previous(), vt);
@@ -7295,15 +7299,55 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, const
72957299
}
72967300

72977301
// c++17 auto type deduction of braced init list
7298-
if (parent->isCpp() && mSettings.standards.cpp >= Standards::CPP17 && vt2 && Token::Match(parent->tokAt(-2), "auto %var% {")) {
7299-
Token *autoTok = parent->tokAt(-2);
7300-
setValueType(autoTok, *vt2);
7301-
setAutoTokenProperties(autoTok);
7302-
if (parent->previous()->variable())
7303-
const_cast<Variable*>(parent->previous()->variable())->setValueType(*vt2);
7304-
else
7305-
debugMessage(parent->previous(), "debug", "Missing variable class for variable with varid");
7306-
return;
7302+
if (parent->isCpp() && mSettings.standards.cpp >= Standards::CPP17
7303+
&& Token::Match(parent->astOperand1(), "%var% {") && vt2) {
7304+
7305+
auto reference = Reference::None;
7306+
nonneg int pointer = 0;
7307+
nonneg int constness = 0;
7308+
nonneg int volatileness = 0;
7309+
7310+
Token *varTok = parent->astOperand1();
7311+
Token *typeTok = varTok->previous();
7312+
7313+
while (Token::Match(typeTok, "&|&&|*|const|volatile")) {
7314+
if (typeTok->str() == "&")
7315+
reference = Reference::LValue;
7316+
else if (typeTok->str() == "&&")
7317+
reference = Reference::RValue;
7318+
else if (typeTok->str() == "*")
7319+
pointer++;
7320+
else if (typeTok->str() == "const")
7321+
constness |= 1 << pointer;
7322+
else if (typeTok->str() == "volatile")
7323+
volatileness |= 1 << pointer;
7324+
typeTok = typeTok->previous();
7325+
}
7326+
7327+
if (typeTok->str() == "auto") {
7328+
setValueType(typeTok, *vt2);
7329+
setAutoTokenProperties(typeTok);
7330+
7331+
auto *varVt = new ValueType(*vt2);
7332+
7333+
varVt->reference = reference;
7334+
varVt->constness |= constness;
7335+
varVt->volatileness |= volatileness;
7336+
7337+
if (Token::simpleMatch(typeTok->previous(), "const auto"))
7338+
varVt->constness |= 1 << pointer;
7339+
7340+
if (Token::simpleMatch(typeTok->previous(), "volatile auto"))
7341+
varVt->volatileness |= 1 << pointer;
7342+
7343+
varTok->setValueType(varVt);
7344+
7345+
if (varTok->variable())
7346+
const_cast<Variable*>(varTok->variable())->setValueType(*varVt);
7347+
else
7348+
debugMessage(varTok, "debug", "Missing variable class for variable with varid");
7349+
return;
7350+
}
73077351
}
73087352

73097353
if (!vt1)

test/testsymboldatabase.cpp

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,8 @@ class TestSymbolDatabase : public TestFixture {
220220
TEST_CASE(VariableValueType4); // smart pointer type
221221
TEST_CASE(VariableValueType5); // smart pointer type
222222
TEST_CASE(VariableValueType6); // smart pointer type
223+
TEST_CASE(VariableValueType7);
224+
TEST_CASE(VariableValueType8);
223225
TEST_CASE(VariableValueTypeReferences);
224226
TEST_CASE(VariableValueTypeTemplate);
225227

@@ -1316,6 +1318,71 @@ class TestSymbolDatabase : public TestFixture {
13161318
ASSERT(check->valueType()->smartPointerTypeToken);
13171319
}
13181320

1321+
void VariableValueType7() {
1322+
GET_SYMBOL_DB("void f() {\n"
1323+
" auto x0 = 0;\n"
1324+
" auto &x1 = x0;\n"
1325+
" auto &x2 {x0};\n"
1326+
" auto &&x3 = 0;\n"
1327+
" auto &&x4 {0};\n"
1328+
"}\n");
1329+
1330+
const Token* x1 = Token::findsimplematch(tokenizer.tokens(), "x1");
1331+
const Token* x2 = Token::findsimplematch(tokenizer.tokens(), "x2");
1332+
const Token* x3 = Token::findsimplematch(tokenizer.tokens(), "x3");
1333+
const Token* x4 = Token::findsimplematch(tokenizer.tokens(), "x4");
1334+
1335+
ASSERT(x1);
1336+
ASSERT(x2);
1337+
ASSERT(x3);
1338+
ASSERT(x4);
1339+
1340+
ASSERT_EQUALS_ENUM(ValueType::INT, x1->valueType()->type);
1341+
ASSERT_EQUALS_ENUM(ValueType::INT, x2->valueType()->type);
1342+
ASSERT_EQUALS_ENUM(ValueType::INT, x3->valueType()->type);
1343+
ASSERT_EQUALS_ENUM(ValueType::INT, x4->valueType()->type);
1344+
1345+
ASSERT_EQUALS_ENUM(Reference::LValue, x1->valueType()->reference);
1346+
ASSERT_EQUALS_ENUM(Reference::LValue, x2->valueType()->reference);
1347+
ASSERT_EQUALS_ENUM(Reference::RValue, x3->valueType()->reference);
1348+
ASSERT_EQUALS_ENUM(Reference::RValue, x4->valueType()->reference);
1349+
}
1350+
1351+
void VariableValueType8() {
1352+
GET_SYMBOL_DB("void f() {\n"
1353+
" char buf[128];\n"
1354+
" const auto *const x0 {buf};\n"
1355+
" auto *const x1 {buf};\n"
1356+
" const auto *x2 {buf};\n"
1357+
" auto x3 {buf};\n"
1358+
"}\n");
1359+
1360+
const Token* x0 = Token::findsimplematch(tokenizer.tokens(), "x0");
1361+
const Token* x1 = Token::findsimplematch(tokenizer.tokens(), "x1");
1362+
const Token* x2 = Token::findsimplematch(tokenizer.tokens(), "x2");
1363+
const Token* x3 = Token::findsimplematch(tokenizer.tokens(), "x3");
1364+
1365+
ASSERT(x0);
1366+
ASSERT(x1);
1367+
ASSERT(x2);
1368+
ASSERT(x3);
1369+
1370+
ASSERT_EQUALS_ENUM(ValueType::CHAR, x0->valueType()->type);
1371+
ASSERT_EQUALS_ENUM(ValueType::CHAR, x1->valueType()->type);
1372+
ASSERT_EQUALS_ENUM(ValueType::CHAR, x2->valueType()->type);
1373+
ASSERT_EQUALS_ENUM(ValueType::CHAR, x3->valueType()->type);
1374+
1375+
ASSERT_EQUALS(3, x0->valueType()->constness);
1376+
ASSERT_EQUALS(1, x1->valueType()->constness);
1377+
ASSERT_EQUALS(2, x2->valueType()->constness);
1378+
ASSERT_EQUALS(0, x3->valueType()->constness);
1379+
1380+
ASSERT_EQUALS(1, x0->valueType()->pointer);
1381+
ASSERT_EQUALS(1, x1->valueType()->pointer);
1382+
ASSERT_EQUALS(1, x2->valueType()->pointer);
1383+
ASSERT_EQUALS(1, x3->valueType()->pointer);
1384+
}
1385+
13191386
void VariableValueTypeReferences() {
13201387
{
13211388
GET_SYMBOL_DB("void foo(int x) {}\n");

0 commit comments

Comments
 (0)