From 2a8296879c9f2f43d13b701ee372217cf6c67b8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 23 Jun 2018 16:42:36 +0200 Subject: [PATCH] CheckOther: Use Variable::valueType() instead of Variable::typeStartToken --- lib/checkother.cpp | 10 +++------- lib/library.cpp | 24 ++++++++++++++---------- test/testsymboldatabase.cpp | 9 +++++++++ 3 files changed, 26 insertions(+), 17 deletions(-) diff --git a/lib/checkother.cpp b/lib/checkother.cpp index c5e4b847b..46e4b0f70 100644 --- a/lib/checkother.cpp +++ b/lib/checkother.cpp @@ -1425,11 +1425,7 @@ void CheckOther::checkPassByReference() bool inconclusive = false; - const Token* const tok = var->typeStartToken(); - if (var->isStlStringType()) { - ; - } else if (var->isStlType() && Token::Match(tok, "std :: %type% <") && !Token::simpleMatch(tok->linkAt(3), "> ::") && !Token::Match(tok->tokAt(2), "initializer_list|weak_ptr|auto_ptr|unique_ptr|shared_ptr|function|pair")) { - ; + if (var->valueType()->type == ValueType::Type::CONTAINER) { } else if (var->type() && !var->type()->isEnumType()) { // Check if type is a struct or class. // Ensure that it is a large object. if (!var->type()->classScope) @@ -1444,7 +1440,7 @@ void CheckOther::checkPassByReference() const bool isConst = var->isConst(); if (isConst) { - passedByValueError(tok, var->name(), inconclusive); + passedByValueError(var->nameToken(), var->name(), inconclusive); continue; } @@ -1453,7 +1449,7 @@ void CheckOther::checkPassByReference() continue; if (canBeConst(var)) { - passedByValueError(tok, var->name(), inconclusive); + passedByValueError(var->nameToken(), var->name(), inconclusive); } } } diff --git a/lib/library.cpp b/lib/library.cpp index 28c86a5bc..452a065eb 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -904,17 +904,21 @@ const Library::Container* Library::detectContainer(const Token* typeStart, bool if (container.startPattern.empty()) continue; - if (Token::Match(typeStart, container.startPattern.c_str())) { - if (!iterator && container.endPattern.empty()) // If endPattern is undefined, it will always match, but itEndPattern has to be defined. - return &container; + if (!endsWith(container.startPattern, '<')) { + if (!Token::Match(typeStart, (container.startPattern + " !!::").c_str())) + continue; + } else if (!Token::Match(typeStart, (container.startPattern + " !!::").c_str())) + continue; - for (const Token* tok = typeStart; tok && !tok->varId(); tok = tok->next()) { - if (tok->link()) { - const std::string& endPattern = iterator ? container.itEndPattern : container.endPattern; - if (Token::Match(tok->link(), endPattern.c_str())) - return &container; - break; - } + if (!iterator && container.endPattern.empty()) // If endPattern is undefined, it will always match, but itEndPattern has to be defined. + return &container; + + for (const Token* tok = typeStart; tok && !tok->varId(); tok = tok->next()) { + if (tok->link()) { + const std::string& endPattern = iterator ? container.itEndPattern : container.endPattern; + if (Token::Match(tok->link(), endPattern.c_str())) + return &container; + break; } } } diff --git a/test/testsymboldatabase.cpp b/test/testsymboldatabase.cpp index 759a6d702..963f6f663 100644 --- a/test/testsymboldatabase.cpp +++ b/test/testsymboldatabase.cpp @@ -148,6 +148,7 @@ private: TEST_CASE(VariableValueType1); TEST_CASE(VariableValueType2); + TEST_CASE(VariableValueType3); TEST_CASE(findVariableType1); TEST_CASE(findVariableType2); @@ -808,6 +809,14 @@ private: ASSERT(x->valueType()->isIntegral()); } + void VariableValueType3() { + GET_SYMBOL_DB("void f(std::string::size_type x);\n"); + const Variable* x = db->getVariableFromVarId(1); + ASSERT_EQUALS("x", x->name()); + // TODO: Configure std::string::size_type somehow. + TODO_ASSERT_EQUALS(ValueType::Type::LONGLONG, ValueType::Type::UNKNOWN_TYPE, x->valueType()->type); + } + void findVariableType1() { GET_SYMBOL_DB("class A {\n" "public:\n"