From 8ad3e43f92505ce900cbeaf59c5b74fc4b23063a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Fri, 12 Jul 2019 16:05:08 +0200 Subject: [PATCH] Add handling of a simple C++ contract --- lib/tokenize.cpp | 22 ++++++++++++++++++++++ test/testvalueflow.cpp | 8 ++++++++ 2 files changed, 30 insertions(+) diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 9753e1028..416e7650b 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -9839,6 +9839,28 @@ void Tokenizer::simplifyCPPAttribute() else head->previous()->isAttributeNodiscard(true); } + } else if (Token::Match(tok->previous(), ") [ [ expects|ensures|assert default|audit|axiom| : %name% <|<=|>|>= %num% ] ]")) { + const Token *vartok = tok->tokAt(4); + if (vartok->str() == ":") + vartok = vartok->next(); + Token *argtok = tok->tokAt(-2); + while (argtok && argtok->str() != "(") { + if (argtok->str() == vartok->str()) + break; + if (argtok->str() == ")") + argtok = argtok->link(); + argtok = argtok->previous(); + } + if (argtok && argtok->str() == vartok->str()) { + if (vartok->next()->str() == ">=") + argtok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::LOW, MathLib::toLongNumber(vartok->strAt(2))); + else if (vartok->next()->str() == ">") + argtok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::LOW, MathLib::toLongNumber(vartok->strAt(2))+1); + else if (vartok->next()->str() == "<=") + argtok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::HIGH, MathLib::toLongNumber(vartok->strAt(2))); + else if (vartok->next()->str() == "<") + argtok->setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type::HIGH, MathLib::toLongNumber(vartok->strAt(2))-1); + } } Token::eraseTokens(tok, tok->link()->next()); tok->deleteThis(); diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index b5d59b88c..a5855b910 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -3927,6 +3927,14 @@ private: ASSERT_EQUALS(2, values.size()); ASSERT_EQUALS(0, values.front().intvalue); ASSERT_EQUALS(100, values.back().intvalue); + + code = "void f(unsigned short x) [[expects: x <= 100]] {\n" + " return x + 0;\n" + "}"; + values = tokenValues(code, "+", &s); + ASSERT_EQUALS(2, values.size()); + ASSERT_EQUALS(0, values.front().intvalue); + ASSERT_EQUALS(100, values.back().intvalue); }