Skip to content

Instantly share code, notes, and snippets.

@darcyliu
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save darcyliu/571e33a5be2440132a77 to your computer and use it in GitHub Desktop.
Save darcyliu/571e33a5be2440132a77 to your computer and use it in GitHub Desktop.
ArrayOperationsChecker
#include "ClangSACheckers.h"
#include "clang/StaticAnalyzer/Core/BugReporter/BugType.h"
#include "clang/StaticAnalyzer/Core/Checker.h"
#include "clang/StaticAnalyzer/Core/CheckerManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CheckerContext.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/ConstraintManager.h"
#include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h"
#include <cstdio>
#include <iostream>
using namespace clang;
using namespace ento;
namespace {
class ArrayOperationsChecker :
public Checker<
check::Location,
check::EndFunction,
check::PreCall,
//check::PostCall,
//check::EndOfTranslationUnit
//eval::Call
check::EndAnalysis
> {
mutable std::unique_ptr<BuiltinBug> BT;
public:
mutable int aread = 0;
mutable int awrite = 0;
mutable std::string fun_name;
// void checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
// AnalysisManager& mgr,
// BugReporter &BR) const;
// bool evalCall(const CallExpr *CE, CheckerContext &C) const;
void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
void checkEndAnalysis(ExplodedGraph &G, BugReporter &B,ExprEngine &Eng) const;
void checkEndFunction(CheckerContext &C) const;
void checkLocation(SVal l, bool isLoad, const Stmt* S,
CheckerContext &C) const;
};
}
// void ArrayOperationsChecker::checkEndOfTranslationUnit(const TranslationUnitDecl *TU,
// AnalysisManager& mgr,
// BugReporter &BR) const {
// llvm::outs() << "checkEndOfTranslationUnit\n";
// }
// bool ArrayOperationsChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
// // std::cout << "evalCall\n";
// // llvm::errs() << C.getCalleeName(CE) << " is called\n";
// return false;
// }
void ArrayOperationsChecker::checkPreCall(const CallEvent &Call, CheckerContext &C) const {
const IdentifierInfo *ID = Call.getCalleeIdentifier();
if(ID == NULL) {
fun_name = std::string("unknown");
return;
}
// llvm::errs() << ID->getName() << " is called\n";
fun_name = std::string(ID->getName());
if (fun_name.length() == 0){
fun_name = std::string("unknown");
}
}
void ArrayOperationsChecker::checkEndAnalysis(ExplodedGraph &G,
BugReporter &B,
ExprEngine &Eng) const {
//llvm::outs() << "checkEndAnalysis\n";
}
void ArrayOperationsChecker::checkEndFunction(CheckerContext &C) const {
llvm::outs() << "method "<< fun_name << ": reads = " << aread << ";writes= " << awrite;
llvm::outs() << "\n";
aread = 0;
awrite = 0;
fun_name = std::string("");
//llvm::outs() << "--END FUNCTION--\n";
}
void ArrayOperationsChecker::checkLocation(SVal l, bool isLoad, const Stmt* LoadS,
CheckerContext &C) const {
const MemRegion *R = l.getAsRegion();
if (!R)
return;
const ElementRegion *ER = dyn_cast<ElementRegion>(R);
if (!ER)
return;
if (isLoad){
aread ++;
} else {
awrite ++;
}
//std::cout << std::endl<< "reads = " << aread << ";writes= " << awrite << std::endl;
}
void ento::registerArrayOperationsChecker(CheckerManager &mgr) {
mgr.registerChecker<ArrayOperationsChecker>();
}
method test: reads = 20;writes= 10
method test_case: reads = 0;writes= 0
method test_case1: reads = 5;writes= 10
method test_case2: reads = 1;writes= 0
method test_case3: reads = 1;writes= 1
method test_case4: reads = 0;writes= 5
method test_case4: reads = 0;writes= 3
method : reads = 0;writes= 0
#include <stdio.h>
int *test(int *b, int *c) {
static int a[10];
for (int i=0; i<10; i++) {
a[i] = b[i] + c[i];
}
return a;
}
void test_case() {
}
void test_case1() {
int a[10];
for (int i = 0; i < 10; ++i) {
if (i%2 == 0){
a[i] = i/2;
}else{
a[i] = a[i-1];
}
}
}
void test_case2() {
int a[10] = {0};
a[0];
}
void test_case3() {
int a[10] = {0};
a[0] ++;
}
void test_case4(int len) {
int a[3];
for (int i = 0; i < len; ++i){
a[i] = 0;
}
}
int main(int argc, char **argv) {
int y[] = {1,2,3,4,5,6,7,8,9,0};
int z[] = {1,2,3,4,5,6,7,8,9,0};
int *x = test(y,z);
test_case();
test_case1();
test_case2();
test_case3();
test_case4(5);//stoi('5');
test_case4(3);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment