From 8b9d3f9880824523c16a1101967987f998dc1cb4 Mon Sep 17 00:00:00 2001 From: "Zancanaro; Carlo" Date: Tue, 27 Nov 2012 18:18:41 +1100 Subject: Use stdin to read the Template Constraint Matrix. Better for testing. --- clang/lib/StaticAnalyzer/Checkers/IntervalTest.cpp | 214 +++++++++++++-------- 1 file changed, 134 insertions(+), 80 deletions(-) diff --git a/clang/lib/StaticAnalyzer/Checkers/IntervalTest.cpp b/clang/lib/StaticAnalyzer/Checkers/IntervalTest.cpp index c1e0273..8a3ef6e 100644 --- a/clang/lib/StaticAnalyzer/Checkers/IntervalTest.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/IntervalTest.cpp @@ -4,6 +4,7 @@ #include "clang/Analysis/Analyses/Interval.h" #include "clang/Analysis/CallGraph.h" #include "llvm/Support/Process.h" +#include using namespace clang; using namespace ento; @@ -12,111 +13,164 @@ using namespace std; #include template string toString(const T& obj) { - stringstream stream; - stream << obj; - return stream.str(); +stringstream stream; +stream << obj; +return stream.str(); +} + +#include +#include +#include +#include + +// trim from start +static inline std::string <rim(std::string &s) { + s.erase(s.begin(), std::find_if(s.begin(), s.end(), std::not1(std::ptr_fun(std::isspace)))); + return s; +} + +// trim from end +static inline std::string &rtrim(std::string &s) { + s.erase(std::find_if(s.rbegin(), s.rend(), std::not1(std::ptr_fun(std::isspace))).base(), s.end()); + return s; +} + +// trim from both ends +static inline std::string &trim(std::string &s) { + return ltrim(rtrim(s)); } namespace { class IntervalTest: public Checker { public: - void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, - BugReporter &BR) const { - if (IntervalAnalysis *a = mgr.getAnalysis(D)) { - CFG* cfg = mgr.getCFG(D); +void checkASTCodeBody(const Decl *D, AnalysisManager& mgr, + BugReporter &BR) const { + if (IntervalAnalysis *a = mgr.getAnalysis(D)) { + /*CFG* cfg = mgr.getCFG(D); - set variables; + set variables; - if (const FunctionDecl* func = dyn_cast(D)) { - for (unsigned int i = func->getNumParams(); i > 0; i--) { - variables.insert(func->getParamDecl(i-1)->getNameAsString()); - } + if (const FunctionDecl* func = dyn_cast(D)) { + for (unsigned int i = func->getNumParams(); i > 0; i--) { + variables.insert(func->getParamDecl(i-1)->getNameAsString()); } - for (CFG::iterator - it = cfg->begin(), - ei = cfg->end(); - it != ei; - ++it) { - for (CFGBlock::iterator - block_it = (*it)->begin(), - block_end = (*it)->end(); - block_it != block_end; - block_it++) { - const CFGStmt* cfg_stmt = block_it->getAs(); - const Stmt* stmt = cfg_stmt->getStmt(); - if (stmt->getStmtClass() == Stmt::BinaryOperatorClass) { - const BinaryOperator* binop = static_cast(stmt); - if (binop->isAssignmentOp()) { - const Expr* left = binop->getLHS()->IgnoreParenCasts(); - if (left->getStmtClass() == Stmt::DeclRefExprClass) { - variables.insert(static_cast(left)->getNameInfo().getAsString()); - } + } + for (CFG::iterator + it = cfg->begin(), + ei = cfg->end(); + it != ei; + ++it) { + for (CFGBlock::iterator + block_it = (*it)->begin(), + block_end = (*it)->end(); + block_it != block_end; + block_it++) { + const CFGStmt* cfg_stmt = block_it->getAs(); + const Stmt* stmt = cfg_stmt->getStmt(); + if (stmt->getStmtClass() == Stmt::BinaryOperatorClass) { + const BinaryOperator* binop = static_cast(stmt); + if (binop->isAssignmentOp()) { + const Expr* left = binop->getLHS()->IgnoreParenCasts(); + if (left->getStmtClass() == Stmt::DeclRefExprClass) { + variables.insert(static_cast(left)->getNameInfo().getAsString()); } - } else if (stmt->getStmtClass() == Stmt::DeclStmtClass) { - const DeclStmt* decl_stmt = static_cast(stmt); - for (DeclStmt::const_decl_iterator jt = decl_stmt->decl_begin(), - ej = decl_stmt->decl_end(); - jt != ej; - ++jt) { - if ((*jt)->getKind() == Decl::Var) { - const VarDecl* decl = static_cast(*jt); - variables.insert(decl->getNameAsString()); - jt++; - if (jt != ej) { - llvm::errs() << "Only the first declaration in a multi-declaration statement is used.\n"; - } - break; // only take the first one, for now + } + } else if (stmt->getStmtClass() == Stmt::DeclStmtClass) { + const DeclStmt* decl_stmt = static_cast(stmt); + for (DeclStmt::const_decl_iterator jt = decl_stmt->decl_begin(), + ej = decl_stmt->decl_end(); + jt != ej; + ++jt) { + if ((*jt)->getKind() == Decl::Var) { + const VarDecl* decl = static_cast(*jt); + variables.insert(decl->getNameAsString()); + jt++; + if (jt != ej) { + llvm::errs() << "Only the first declaration in a multi-declaration statement is used.\n"; } + break; // only take the first one, for now } } } } + } + vector labels; + ConstraintMatrix T; + set::iterator end = variables.end(); + for (set::iterator it = variables.begin(); + it != end; + ++it) { + map pos_row; + pos_row[*it] = 1; + T.push_back(pos_row); + labels.push_back(*it); + map neg_row; + neg_row[*it] = -1; + T.push_back(neg_row); + labels.push_back("-" + *it); - vector labels; - ConstraintMatrix T; - set::iterator end = variables.end(); - for (set::iterator it = variables.begin(); - it != end; - ++it) { - map pos_row; - pos_row[*it] = 1; - T.push_back(pos_row); - labels.push_back(*it); - - map neg_row; - neg_row[*it] = -1; - T.push_back(neg_row); - labels.push_back("-" + *it); - - for (set::iterator jt = variables.begin(); - jt != end; - ++jt) { - if (it != jt) { - map diff_row; - diff_row[*it] = 1; - diff_row[*jt] = -1; - T.push_back(diff_row); - labels.push_back(*it + " - " + *jt); - } + for (set::iterator jt = variables.begin(); + jt != end; + ++jt) { + if (it != jt) { + map diff_row; + diff_row[*it] = 1; + diff_row[*jt] = -1; + T.push_back(diff_row); + labels.push_back(*it + " - " + *jt); } } + }*/ - map > result = a->runOnAllBlocks(*D, T); + vector labels; + ConstraintMatrix T; + while (cin.good()) { + string line; + getline(cin, line); + trim(line); - for (map >::iterator - it = result.begin(), - ei = result.end(); - it != ei; - ++it) { - llvm::errs() << "Block " << toString(it->first->getBlockID()) << ": \n"; - for (unsigned int i = 0; i < T.size(); ++i) { - llvm::errs() << "\t" << labels[i] << " <= " << toString(it->second[i]) << "\n"; + if (line.length() == 0) + continue; + + map row; + size_t neg_sign_index = line.find('-'); + if (neg_sign_index == string::npos) { + row[line] = 1; + labels.push_back(line); + } else if (neg_sign_index == 0) { + row[line.substr(1)] = -1; + labels.push_back('-'+line.substr(1)); + } else { + string left = line.substr(0, neg_sign_index); + string right = line.substr(neg_sign_index+1); + trim(left); + trim(right); + if (left != right) { + row[left] = 1; + row[right] = -1; } + labels.push_back(left + '-' + right); + } + T.push_back(row); + } + + + map > result = a->runOnAllBlocks(*D, T); + + for (map >::iterator + it = result.begin(), + ei = result.end(); + it != ei; + ++it) { + llvm::errs() << "Block " << toString(it->first->getBlockID()) << ": \n"; + for (unsigned int i = 0; i < T.size(); ++i) { + llvm::errs() << "\t" << labels[i] << " <= " << toString(it->second[i]) << "\n"; } } } +} }; } -- cgit v1.2.3