Clang; run ValueFlow analysis

This commit is contained in:
Daniel Marjamäki 2020-01-11 13:04:51 +01:00
parent 9c38a659a1
commit 052eaba632
5 changed files with 17 additions and 6 deletions

View File

@ -247,10 +247,10 @@ unsigned int CppCheck::check(const std::string &path)
const std::string clang = Path::isCPP(path) ? "clang++" : "clang"; const std::string clang = Path::isCPP(path) ? "clang++" : "clang";
/* Experimental: import clang ast dump */ /* Experimental: import clang ast dump */
std::ofstream fout("temp.c"); std::ofstream fout("__temp__.c");
fout << "int x;\n"; fout << "int x;\n";
fout.close(); 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<bool, std::string> res1 = executeCommand(cmd1); const std::pair<bool, std::string> res1 = executeCommand(cmd1);
if (!res1.first) { if (!res1.first) {
std::cerr << "Failed to execute '" + cmd1 + "'" << std::endl; 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 tokenizer(&mSettings, this);
tokenizer.list.appendFileIfNew(path); tokenizer.list.appendFileIfNew(path);
clangimport::parseClangAstDump(&tokenizer, ast); clangimport::parseClangAstDump(&tokenizer, ast);
//ValueFlow::setValues(&tokenizer.list, const_cast<SymbolDatabase *>(tokenizer.getSymbolDatabase()), this, &mSettings); ValueFlow::setValues(&tokenizer.list, const_cast<SymbolDatabase *>(tokenizer.getSymbolDatabase()), this, &mSettings);
if (mSettings.debugnormal) if (mSettings.debugnormal)
tokenizer.printDebugOutput(1); tokenizer.printDebugOutput(1);

View File

@ -339,7 +339,7 @@ void execute(const Token *expr,
if (intValue == 0 && if (intValue == 0 &&
expr->str() == "--" && expr->str() == "--" &&
expr->astOperand1()->variable() && expr->astOperand1()->variable() &&
expr->astOperand1()->variable()->typeStartToken()->isUnsigned()) expr->astOperand1()->variable()->isUnsigned())
*error = true; // overflow *error = true; // overflow
*result = intValue + (expr->str() == "++" ? 1 : -1); *result = intValue + (expr->str() == "++" ? 1 : -1);
programMemory->setIntValue(expr->astOperand1()->varId(), *result); programMemory->setIntValue(expr->astOperand1()->varId(), *result);

View File

@ -1766,6 +1766,11 @@ bool Variable::isPointerArray() const
return isArray() && nameToken() && nameToken()->previous() && (nameToken()->previous()->str() == "*"); 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 const Token * Variable::declEndToken() const
{ {
Token const * declEnd = typeStartToken(); Token const * declEnd = typeStartToken();

View File

@ -480,6 +480,12 @@ public:
return getFlag(fIsRValueRef); 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. * Does variable have a default value.
* @return true if has a default falue, false if not * @return true if has a default falue, false if not

View File

@ -1996,14 +1996,14 @@ static void valueFlowBeforeCondition(TokenList *tokenlist, SymbolDatabase *symbo
if (Token::Match(tok, "<|>")) { if (Token::Match(tok, "<|>")) {
if (num != 0) if (num != 0)
continue; continue;
if (var->valueType() && var->valueType()->sign != ValueType::Sign::UNSIGNED) if (var->isUnsigned())
continue; continue;
} }
ValueFlow::Value val(tok, num); ValueFlow::Value val(tok, num);
val.varId = varid; val.varId = varid;
ValueFlow::Value val2; ValueFlow::Value val2;
if (num==1U && Token::Match(tok,"<=|>=")) { if (num==1U && Token::Match(tok,"<=|>=")) {
if (var->typeStartToken()->isUnsigned()) { if (var->isUnsigned()) {
val2 = ValueFlow::Value(tok,0); val2 = ValueFlow::Value(tok,0);
val2.varId = varid; val2.varId = varid;
} }