static json::Object createTextRegion(SourceRange R, const SourceManager &SM) { return json::Object{ {"startLine", SM.getExpansionLineNumber(R.getBegin())}, {"endLine", SM.getExpansionLineNumber(R.getEnd())}, {"startColumn", SM.getExpansionColumnNumber(R.getBegin())}, {"endColumn", SM.getExpansionColumnNumber(R.getEnd())}}; }
/// Find the suitable set of lines to show to include a set of ranges. static llvm::Optional<std::pair<unsigned, unsigned>> findLinesForRange(const CharSourceRange &R, FileID FID, const SourceManager &SM) { if (!R.isValid()) return None; SourceLocation Begin = R.getBegin(); SourceLocation End = R.getEnd(); if (SM.getFileID(Begin) != FID || SM.getFileID(End) != FID) return None; return std::make_pair(SM.getExpansionLineNumber(Begin), SM.getExpansionLineNumber(End)); }
void MisleadingIndentationCheck::danglingElseCheck(const SourceManager &SM, const IfStmt *If) { SourceLocation IfLoc = If->getIfLoc(); SourceLocation ElseLoc = If->getElseLoc(); if (IfLoc.isMacroID() || ElseLoc.isMacroID()) return; if (SM.getExpansionLineNumber(If->getThen()->getLocEnd()) == SM.getExpansionLineNumber(ElseLoc)) return; if (SM.getExpansionColumnNumber(IfLoc) != SM.getExpansionColumnNumber(ElseLoc)) diag(ElseLoc, "different indentation for 'if' and corresponding 'else'"); }
SourceRange StackAddrEscapeChecker::GenName(raw_ostream &os, const MemRegion *R, SourceManager &SM) { // Get the base region, stripping away fields and elements. R = R->getBaseRegion(); SourceRange range; os << "Address of "; // Check if the region is a compound literal. if (const CompoundLiteralRegion* CR = dyn_cast<CompoundLiteralRegion>(R)) { const CompoundLiteralExpr *CL = CR->getLiteralExpr(); os << "stack memory associated with a compound literal " "declared on line " << SM.getExpansionLineNumber(CL->getLocStart()) << " returned to caller"; range = CL->getSourceRange(); } else if (const AllocaRegion* AR = dyn_cast<AllocaRegion>(R)) { const Expr *ARE = AR->getExpr(); SourceLocation L = ARE->getLocStart(); range = ARE->getSourceRange(); os << "stack memory allocated by call to alloca() on line " << SM.getExpansionLineNumber(L); } else if (const BlockDataRegion *BR = dyn_cast<BlockDataRegion>(R)) { const BlockDecl *BD = BR->getCodeRegion()->getDecl(); SourceLocation L = BD->getLocStart(); range = BD->getSourceRange(); os << "stack-allocated block declared on line " << SM.getExpansionLineNumber(L); } else if (const VarRegion *VR = dyn_cast<VarRegion>(R)) { os << "stack memory associated with local variable '" << VR->getString() << '\''; range = VR->getDecl()->getSourceRange(); } else if (const CXXTempObjectRegion *TOR = dyn_cast<CXXTempObjectRegion>(R)) { os << "stack memory associated with temporary object of type '" << TOR->getValueType().getAsString() << '\''; range = TOR->getExpr()->getSourceRange(); } else { llvm_unreachable("Invalid region in ReturnStackAddressChecker."); } return range; }
bool DoubleFetchChecker::diffTaintInBranch(ProgramStateRef state, SVal val, const Stmt* LoadS, SourceManager &mgr) const{ //assert(ifTainted(state, arg)); TaintList tl; std::list<TAINT>::iterator i, j; GlobalBranchesTy GB = state->get<GlobalBranches>(); GlobalBranchesTy::iterator I, E; I = GB.begin(); E = GB.end(); /*Get the GlobalBranch list, * which should be pointed by iterator I. */ if(I != E){ /*get the taints of val, stored in tl*/ bool ret = this->getSingleTaintListByTime(tl, state, val); if(ret) tl.showTaints("--->(diffTaintInBranch)-val: "); /* check if Expr (in the form of loc) within a controlled branch, * return the taintlist of that branch, stored in btl. * otherwise return null * LoadS is Expr*/ unsigned int location = mgr.getExpansionLineNumber(LoadS->getLocStart()); if( GlobalFuncTable.getNameByLoc(location) == "get_user"){ std::cout<<"--->(it is source func, return)\n"; return false; } std::cout<<"--->(diffTaintInBranch) location: "<<location<<std::endl; TaintList * btl = (*I).getBranchTLbyExprLoc(location); if ( btl != NULL){ if(btl->isEmpty()) std::cout<<"--->(get empty)\n"; btl->showTaints("--->(diffTaintInBranch)-branch: "); for (i = tl.getList().begin(); i != tl.getList().end(); i++) { for (j = btl->getList().begin(); j!= btl->getList().end(); j++){ if (((*i).taint != (*j).taint) && ((*i).origin == (*j).origin)){ printf("DDDDDDDDFFFFFF!!!!!!!!!!!!!!!!!!!!!!!!\n"); return true; } } } } else std::cout<<"--->(diffTaintInBranch) : get controlled branch taintlist failed.\n"; } else std::cout<<"--->(diffTaintInBranch) : get GlobalBranchesTy failed, probably no branch yet.\n"; return false; }
std::string toString(SourceManager& sourceManager, SourceLocation loc) { //return loc.printToString(sourceManager); std::string fileName = sourceManager.getFilename(loc).str(); if (fileName.length() > 30) fileName = fileName.substr(fileName.length() - 30); std::ostringstream os; os << fileName << ":" << sourceManager.getExpansionLineNumber(loc) << ":" << sourceManager.getExpansionColumnNumber(loc); return os.str(); }
//both the branch and the arg are tainted, and by different taints //if TaintList - Branch != Empty or BranchTaint - List != Empty then return true //This function can be further accelerated. bool DoubleFetchChecker::diffTaintInBranch(ProgramStateRef state, SVal arg, const Expr * erg, SourceManager &mgr) const{ assert(ifTainted(state, arg)); std::cout<<"(isInTaintedBranch)"<< "\t arg = "<<toStr(arg)<<std::endl; unsigned int loc = mgr.getExpansionLineNumber(erg->getExprLoc()); unsigned int time = this->getCurTime(state); //get the taint of arg, stored in tl TaintList tl; bool ret = this->getSingleTaintListByTime(tl, state,arg, time); std::list<TAINT>::iterator i, j; GlobalBranchesTy GB = state->get<GlobalBranches>(); GlobalBranchesTy::iterator I, E; I = GB.begin(); E = GB.end(); if(I != E){ //printf("hello\n"); //if exp in a controlled branch, return the taintlist of that branch, otherwise return null TaintList * btl = (*I).exprInTaintedBranch(erg, loc); if (btl){ for (i = tl.getList().begin(); i != tl.getList().end(); i++) { for (j = btl->getList().begin(); j!= btl->getList().end(); j++){ std::cout<<"(diffTaintInBranch) branch taint: "<<(*i).tag<<" val taint:"<<(*j).tag<<"\torigin:" <<toStr((*j).origin)<<std::endl; if (((*i).tag != (*j).tag) && ((*i).origin == (*j).origin)){ //printf("DDDDDDDDFFFFFF\n"); return true; } } } } else std::cout<<"(diffTaintInBranch) : get controlled branch taintlist failed.\n"; } else std::cout<<"(diffTaintInBranch) : get GlobalBranchesTy failed.\n"; //BranchTaintSetTy BT = state->get<BranchTaintSet>(); //BranchTaintSetTy::iterator I, E; tl.showTaints("No diff Taint In Branch-->>"); return false; }
void MisleadingIndentationCheck::missingBracesCheck(const SourceManager &SM, const CompoundStmt *CStmt) { const static StringRef StmtNames[] = {"if", "for", "while"}; for (unsigned int i = 0; i < CStmt->size() - 1; i++) { const Stmt *CurrentStmt = CStmt->body_begin()[i]; const Stmt *Inner = nullptr; int StmtKind = 0; if (const auto *CurrentIf = dyn_cast<IfStmt>(CurrentStmt)) { StmtKind = 0; Inner = CurrentIf->getElse() ? CurrentIf->getElse() : CurrentIf->getThen(); } else if (const auto *CurrentFor = dyn_cast<ForStmt>(CurrentStmt)) { StmtKind = 1; Inner = CurrentFor->getBody(); } else if (const auto *CurrentWhile = dyn_cast<WhileStmt>(CurrentStmt)) { StmtKind = 2; Inner = CurrentWhile->getBody(); } else { continue; } if (isa<CompoundStmt>(Inner)) continue; SourceLocation InnerLoc = Inner->getLocStart(); SourceLocation OuterLoc = CurrentStmt->getLocStart(); if (SM.getExpansionLineNumber(InnerLoc) == SM.getExpansionLineNumber(OuterLoc)) continue; const Stmt *NextStmt = CStmt->body_begin()[i + 1]; SourceLocation NextLoc = NextStmt->getLocStart(); if (InnerLoc.isMacroID() || OuterLoc.isMacroID() || NextLoc.isMacroID()) continue; if (SM.getExpansionColumnNumber(InnerLoc) == SM.getExpansionColumnNumber(NextLoc)) { diag(NextLoc, "misleading indentation: statement is indented too deeply"); diag(OuterLoc, "did you mean this line to be inside this '%0'", DiagnosticIDs::Note) << StmtNames[StmtKind]; } } }
/// \brief Highlight a SourceRange (with ~'s) for any characters on LineNo. static void highlightRange(const CharSourceRange &R, unsigned LineNo, FileID FID, const SourceColumnMap &map, std::string &CaretLine, const SourceManager &SM, const LangOptions &LangOpts) { if (!R.isValid()) return; SourceLocation Begin = R.getBegin(); SourceLocation End = R.getEnd(); unsigned StartLineNo = SM.getExpansionLineNumber(Begin); if (StartLineNo > LineNo || SM.getFileID(Begin) != FID) return; // No intersection. unsigned EndLineNo = SM.getExpansionLineNumber(End); if (EndLineNo < LineNo || SM.getFileID(End) != FID) return; // No intersection. // Compute the column number of the start. unsigned StartColNo = 0; if (StartLineNo == LineNo) { StartColNo = SM.getExpansionColumnNumber(Begin); if (StartColNo) --StartColNo; // Zero base the col #. } // Compute the column number of the end. unsigned EndColNo = map.getSourceLine().size(); if (EndLineNo == LineNo) { EndColNo = SM.getExpansionColumnNumber(End); if (EndColNo) { --EndColNo; // Zero base the col #. // Add in the length of the token, so that we cover multi-char tokens if // this is a token range. if (R.isTokenRange()) EndColNo += Lexer::MeasureTokenLength(End, SM, LangOpts); } else { EndColNo = CaretLine.size(); } } assert(StartColNo <= EndColNo && "Invalid range!"); // Check that a token range does not highlight only whitespace. if (R.isTokenRange()) { // Pick the first non-whitespace column. while (StartColNo < map.getSourceLine().size() && (map.getSourceLine()[StartColNo] == ' ' || map.getSourceLine()[StartColNo] == '\t')) StartColNo = map.startOfNextColumn(StartColNo); // Pick the last non-whitespace column. if (EndColNo > map.getSourceLine().size()) EndColNo = map.getSourceLine().size(); while (EndColNo-1 && (map.getSourceLine()[EndColNo-1] == ' ' || map.getSourceLine()[EndColNo-1] == '\t')) EndColNo = map.startOfPreviousColumn(EndColNo); // If the start/end passed each other, then we are trying to highlight a // range that just exists in whitespace, which must be some sort of other // bug. assert(StartColNo <= EndColNo && "Trying to highlight whitespace??"); } assert(StartColNo <= map.getSourceLine().size() && "Invalid range!"); assert(EndColNo <= map.getSourceLine().size() && "Invalid range!"); // Fill the range with ~'s. StartColNo = map.byteToContainingColumn(StartColNo); EndColNo = map.byteToContainingColumn(EndColNo); assert(StartColNo <= EndColNo && "Invalid range!"); if (CaretLine.size() < EndColNo) CaretLine.resize(EndColNo,' '); std::fill(CaretLine.begin()+StartColNo,CaretLine.begin()+EndColNo,'~'); }
/// \brief Highlight a SourceRange (with ~'s) for any characters on LineNo. void TextDiagnostic::highlightRange(const CharSourceRange &R, unsigned LineNo, FileID FID, const SourceColumnMap &map, std::string &CaretLine, const SourceManager &SM) { if (!R.isValid()) return; SourceLocation Begin = SM.getExpansionLoc(R.getBegin()); SourceLocation End = SM.getExpansionLoc(R.getEnd()); // If the End location and the start location are the same and are a macro // location, then the range was something that came from a macro expansion // or _Pragma. If this is an object-like macro, the best we can do is to // highlight the range. If this is a function-like macro, we'd also like to // highlight the arguments. if (Begin == End && R.getEnd().isMacroID()) End = SM.getExpansionRange(R.getEnd()).second; unsigned StartLineNo = SM.getExpansionLineNumber(Begin); if (StartLineNo > LineNo || SM.getFileID(Begin) != FID) return; // No intersection. unsigned EndLineNo = SM.getExpansionLineNumber(End); if (EndLineNo < LineNo || SM.getFileID(End) != FID) return; // No intersection. // Compute the column number of the start. unsigned StartColNo = 0; if (StartLineNo == LineNo) { StartColNo = SM.getExpansionColumnNumber(Begin); if (StartColNo) --StartColNo; // Zero base the col #. } // Compute the column number of the end. unsigned EndColNo = map.getSourceLine().size(); if (EndLineNo == LineNo) { EndColNo = SM.getExpansionColumnNumber(End); if (EndColNo) { --EndColNo; // Zero base the col #. // Add in the length of the token, so that we cover multi-char tokens if // this is a token range. if (R.isTokenRange()) EndColNo += Lexer::MeasureTokenLength(End, SM, LangOpts); } else { EndColNo = CaretLine.size(); } } assert(StartColNo <= EndColNo && "Invalid range!"); // Check that a token range does not highlight only whitespace. if (R.isTokenRange()) { // Pick the first non-whitespace column. while (StartColNo < map.getSourceLine().size() && (map.getSourceLine()[StartColNo] == ' ' || map.getSourceLine()[StartColNo] == '\t')) ++StartColNo; // Pick the last non-whitespace column. if (EndColNo > map.getSourceLine().size()) EndColNo = map.getSourceLine().size(); while (EndColNo-1 && (map.getSourceLine()[EndColNo-1] == ' ' || map.getSourceLine()[EndColNo-1] == '\t')) --EndColNo; // If the start/end passed each other, then we are trying to highlight a // range that just exists in whitespace, which must be some sort of other // bug. assert(StartColNo <= EndColNo && "Trying to highlight whitespace??"); } assert(StartColNo <= map.getSourceLine().size() && "Invalid range!"); assert(EndColNo <= map.getSourceLine().size() && "Invalid range!"); // Fill the range with ~'s. StartColNo = map.byteToColumn(StartColNo); EndColNo = map.byteToColumn(EndColNo); assert(StartColNo <= EndColNo && "Invalid range!"); if (CaretLine.size() < EndColNo) CaretLine.resize(EndColNo,' '); std::fill(CaretLine.begin()+StartColNo,CaretLine.begin()+EndColNo,'~'); }