From 7ecd5db8fb6240307daf8d0324cdc57233eb988e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Mon, 27 Feb 2017 02:09:33 +0100 Subject: [PATCH] ValueType: Handle auto in range for loop --- lib/symboldatabase.cpp | 27 +++++++++++++++++++++++---- test/testsymboldatabase.cpp | 5 +++-- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 2659c589b..eb27917f4 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -4433,10 +4433,7 @@ static void setValueType(Token *tok, const ValueType &valuetype, bool cpp, Value else if (Token::Match(var1Tok->tokAt(-3), "[;{}] auto *")) autoTok = var1Tok->tokAt(-2); if (autoTok) { - ValueType vt(*vt2); - if (vt.pointer > 0 && autoTok->strAt(1) == "*") - vt.pointer--; - setValueType(autoTok, vt, cpp, defaultSignedness, settings); + setValueType(autoTok, *vt2, cpp, defaultSignedness, settings); setValueType(var1Tok, *vt2, cpp, defaultSignedness, settings); setValueType(parent->previous(), *vt2, cpp, defaultSignedness, settings); } @@ -4489,6 +4486,24 @@ static void setValueType(Token *tok, const ValueType &valuetype, bool cpp, Value return; } + // range for loop, auto + if (vt2 && + parent->str() == ":" && + Token::Match(parent->astParent(), "( const| auto *| %var% :") && + !parent->previous()->valueType() && + Token::simpleMatch(parent->astParent()->astOperand1(), "for")) { + bool isconst = Token::simpleMatch(parent->astParent()->next(), "const"); + Token * const autoToken = const_cast(parent->astParent()->tokAt(isconst ? 2 : 1)); + if (vt2->pointer) { + ValueType vt(*vt2); + vt.pointer--; + if (isconst) + vt.constness |= 1; + setValueType(autoToken, vt, cpp, defaultSignedness, settings); + setValueType(parent->previous(), vt, cpp, defaultSignedness, settings); + } + } + if (!vt1) return; if (parent->astOperand2() && !vt2) @@ -4628,6 +4643,10 @@ static const Token * parsedecl(const Token *type, ValueType * const valuetype, V valuetype->pointer = vt->pointer; if (vt->sign != ValueType::Sign::UNKNOWN_SIGN) valuetype->sign = vt->sign; + valuetype->constness = vt->constness; + while (Token::Match(type, "%name%|*|&|::") && !type->variable()) + type = type->next(); + break; } else if (!valuetype->typeScope && (type->str() == "struct" || type->str() == "enum")) valuetype->type = ValueType::Type::NONSTD; else if (!valuetype->typeScope && type->type() && type->type()->classScope) { diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index a99ac75d6..60aff604b 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -4240,8 +4240,9 @@ private: } // auto variables - ASSERT_EQUALS("signed int", typeOf("; auto x = 3;", "auto")); - ASSERT_EQUALS("signed int", typeOf("; auto *p = (int *)0;", "auto")); + ASSERT_EQUALS("signed int", typeOf("; auto x = 3;", "x")); + ASSERT_EQUALS("signed int *", typeOf("; auto *p = (int *)0;", "p")); + ASSERT_EQUALS("const signed short", typeOf("short values[10]; void f() { for (const auto *x : values); }", "x")); } void variadic1() { // #7453