From 052eaba632d77d2c78f5da44e3106032f34d8bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 11 Jan 2020 13:04:51 +0100 Subject: [PATCH] Clang; run ValueFlow analysis --- lib/cppcheck.cpp | 6 +++--- lib/programmemory.cpp | 2 +- lib/symboldatabase.cpp | 5 +++++ lib/symboldatabase.h | 6 ++++++ lib/valueflow.cpp | 4 ++-- 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/lib/cppcheck.cpp b/lib/cppcheck.cpp index 17053c0c6..b15a21d15 100644 --- a/lib/cppcheck.cpp +++ b/lib/cppcheck.cpp @@ -247,10 +247,10 @@ unsigned int CppCheck::check(const std::string &path) const std::string clang = Path::isCPP(path) ? "clang++" : "clang"; /* Experimental: import clang ast dump */ - std::ofstream fout("temp.c"); + std::ofstream fout("__temp__.c"); fout << "int x;\n"; fout.close(); - const std::string cmd1 = clang + " -v -fsyntax-only temp.c 2>&1"; + const std::string cmd1 = clang + " -v -fsyntax-only __temp__.c 2>&1"; const std::pair res1 = executeCommand(cmd1); if (!res1.first) { std::cerr << "Failed to execute '" + cmd1 + "'" << std::endl; @@ -287,7 +287,7 @@ unsigned int CppCheck::check(const std::string &path) Tokenizer tokenizer(&mSettings, this); tokenizer.list.appendFileIfNew(path); clangimport::parseClangAstDump(&tokenizer, ast); - //ValueFlow::setValues(&tokenizer.list, const_cast(tokenizer.getSymbolDatabase()), this, &mSettings); + ValueFlow::setValues(&tokenizer.list, const_cast(tokenizer.getSymbolDatabase()), this, &mSettings); if (mSettings.debugnormal) tokenizer.printDebugOutput(1); diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index a1d43d0d6..a248c8a1f 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -339,7 +339,7 @@ void execute(const Token *expr, if (intValue == 0 && expr->str() == "--" && expr->astOperand1()->variable() && - expr->astOperand1()->variable()->typeStartToken()->isUnsigned()) + expr->astOperand1()->variable()->isUnsigned()) *error = true; // overflow *result = intValue + (expr->str() == "++" ? 1 : -1); programMemory->setIntValue(expr->astOperand1()->varId(), *result); diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 9690cb3b3..d83497ed1 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1766,6 +1766,11 @@ bool Variable::isPointerArray() const return isArray() && nameToken() && nameToken()->previous() && (nameToken()->previous()->str() == "*"); } +bool Variable::isUnsigned() const +{ + return mValueType ? (mValueType->sign == ValueType::Sign::UNSIGNED) : mTypeStartToken->isUnsigned(); +} + const Token * Variable::declEndToken() const { Token const * declEnd = typeStartToken(); diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 189b3fa4a..dbc39eb55 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -480,6 +480,12 @@ public: return getFlag(fIsRValueRef); } + /** + * Is variable unsigned. + * @return true only if variable _is_ unsigned. if the sign is unknown, false is returned. + */ + bool isUnsigned() const; + /** * Does variable have a default value. * @return true if has a default falue, false if not diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 0ab3069e9..448cebb04 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1996,14 +1996,14 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, SymbolDatabase *symbo if (Token::Match(tok, "<|>")) { if (num != 0) continue; - if (var->valueType() && var->valueType()->sign != ValueType::Sign::UNSIGNED) + if (var->isUnsigned()) continue; } ValueFlow::Value val(tok, num); val.varId = varid; ValueFlow::Value val2; if (num==1U && Token::Match(tok,"<=|>=")) { - if (var->typeStartToken()->isUnsigned()) { + if (var->isUnsigned()) { val2 = ValueFlow::Value(tok,0); val2.varId = varid; }