From 2da75d5af430f3f54f65a518018cef32b13a2cc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Wed, 24 Jul 2019 15:08:04 +0200 Subject: [PATCH] Split up Cppcheck attribute. low and high values can be specified separately and they can be used for variables also. --- cfg/microsoft_sal.cfg | 2 +- lib/tokenize.cpp | 29 +++++++++++++++++++---------- lib/utils.h | 4 +++- test/testvalueflow.cpp | 2 +- 4 files changed, 24 insertions(+), 13 deletions(-) diff --git a/cfg/microsoft_sal.cfg b/cfg/microsoft_sal.cfg index 33b963044..82d4c23c4 100644 --- a/cfg/microsoft_sal.cfg +++ b/cfg/microsoft_sal.cfg @@ -108,7 +108,7 @@ - + diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 34f74428c..9b91a5c6c 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9815,20 +9815,29 @@ void Tokenizer::simplifyCppcheckAttribute() if (attr.compare(attr.size()-2, 2, "__") != 0) // TODO: ends_with("__") continue; - if (attr == "__cppcheck_in_range__") { - Token *vartok = tok->link(); - while (Token::Match(vartok->next(), "%name%|*|&|::")) - vartok = vartok->next(); - if (vartok->isName() && Token::Match(tok, "( %num% , %num% )")) { + Token *vartok = tok->link(); + while (Token::Match(vartok->next(), "%name%|*|&|::")) { + vartok = vartok->next(); + if (Token::Match(vartok, "%name% (") && vartok->str().compare(0,11,"__cppcheck_") == 0) + vartok = vartok->linkAt(1); + } + + if (vartok->isName()) { + if (Token::Match(tok->previous(), "__cppcheck_low__ ( %num% )")) vartok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::LOW, MathLib::toLongNumber(tok->next()->str())); - vartok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::HIGH, MathLib::toLongNumber(tok->strAt(3))); - } + else if (Token::Match(tok->previous(), "__cppcheck_high__ ( %num% )")) + vartok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::HIGH, MathLib::toLongNumber(tok->next()->str())); } // Delete cppcheck attribute.. - tok = tok->previous(); - Token::eraseTokens(tok, tok->linkAt(1)->next()); - tok->deleteThis(); + if (tok->tokAt(-2)) { + tok = tok->tokAt(-2); + Token::eraseTokens(tok, tok->linkAt(2)->next()); + } else { + tok = tok->previous(); + Token::eraseTokens(tok, tok->linkAt(1)->next()); + tok->str(";"); + } } } diff --git a/lib/utils.h b/lib/utils.h index 13f46265d..8a4c291aa 100644 --- a/lib/utils.h +++ b/lib/utils.h @@ -63,7 +63,9 @@ inline static int caseInsensitiveStringCompare(const std::string &lhs, const std #define UNUSED(x) (void)(x) // Use the nonneg macro when you want to assert that a variable/argument is not negative -#ifdef NONNEG +#ifdef __CPPCHECK__ +#define nonneg __cppcheck_low__(0) +#elif defined(NONNEG) // Enable non-negative values checking // TODO : investigate using annotations/contracts for stronger value checking #define nonneg unsigned diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index f63b715a9..f7119bebc 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -3937,7 +3937,7 @@ private: ASSERT(values.front().floatValue < -1E20); ASSERT(values.back().floatValue > 1E20); - code = "short f(__cppcheck_in_range__(0,100) short x) {\n" + code = "short f(__cppcheck_low__(0) __cppcheck_high__(100) short x) {\n" " return x + 0;\n" "}"; values = tokenValues(code, "+", &s);