/// VerifyJumps - Verify each element of the Jumps array to see if they are /// valid, emitting diagnostics if not. void JumpScopeChecker::VerifyJumps() { while (!Jumps.empty()) { Stmt *Jump = Jumps.pop_back_val(); // With a goto, if (GotoStmt *GS = dyn_cast<GotoStmt>(Jump)) { CheckJump(GS, GS->getLabel()->getStmt(), GS->getGotoLoc(), diag::err_goto_into_protected_scope, diag::warn_goto_into_protected_scope, diag::warn_cxx98_compat_goto_into_protected_scope); continue; } // We only get indirect gotos here when they have a constant target. if (IndirectGotoStmt *IGS = dyn_cast<IndirectGotoStmt>(Jump)) { LabelDecl *Target = IGS->getConstantTarget(); CheckJump(IGS, Target->getStmt(), IGS->getGotoLoc(), diag::err_goto_into_protected_scope, diag::warn_goto_into_protected_scope, diag::warn_cxx98_compat_goto_into_protected_scope); continue; } SwitchStmt *SS = cast<SwitchStmt>(Jump); for (SwitchCase *SC = SS->getSwitchCaseList(); SC; SC = SC->getNextSwitchCase()) { assert(LabelAndGotoScopes.count(SC) && "Case not visited?"); CheckJump(SS, SC, SC->getLocStart(), diag::err_switch_into_protected_scope, 0, diag::warn_cxx98_compat_switch_into_protected_scope); } } }
bool VisitStmt(Stmt *s) { // Fill out this function for your homework SourceLocation startLoc = s->getLocStart(); unsigned int lineNum = srcmgr.getExpansionLineNumber(startLoc); unsigned int colNum = srcmgr.getExpansionColumnNumber(startLoc); if (isa<IfStmt>(s)) { printBranchLineColFilename("If", lineNum, colNum, filename); } else if (isa<ForStmt>(s)) { printBranchLineColFilename("For", lineNum, colNum, filename); } else if (isa<WhileStmt>(s)) { printBranchLineColFilename("While", lineNum, colNum, filename); } else if (isa<CaseStmt>(s)) { printBranchLineColFilename("Case", lineNum, colNum, filename); } else if (isa<DoStmt>(s)) { printBranchLineColFilename("Do", lineNum, colNum, filename); } else if (isa<DefaultStmt>(s)) { printBranchLineColFilename("Default", lineNum, colNum, filename); } else if (isa<ConditionalOperator>(s)) { printBranchLineColFilename("?:", lineNum, colNum, filename); } else if (isa<SwitchStmt>(s)) { SwitchStmt *switchstmt = cast<SwitchStmt>(s); SwitchCase *branch = switchstmt->getSwitchCaseList(); bool hasDefault = false; for(; branch != NULL ; branch = branch->getNextSwitchCase()) { if (isa<DefaultStmt>(branch)) { hasDefault = true; break; } } if(!hasDefault) printBranchLineColFilename("ImpDef", lineNum, colNum, filename); } return true; }
/// VerifyJumps - Verify each element of the Jumps array to see if they are /// valid, emitting diagnostics if not. void JumpScopeChecker::VerifyJumps() { while (!Jumps.empty()) { Stmt *Jump = Jumps.pop_back_val(); // With a goto, if (GotoStmt *GS = dyn_cast<GotoStmt>(Jump)) { CheckJump(GS, GS->getLabel(), GS->getGotoLoc(), diag::err_goto_into_protected_scope); continue; } if (SwitchStmt *SS = dyn_cast<SwitchStmt>(Jump)) { for (SwitchCase *SC = SS->getSwitchCaseList(); SC; SC = SC->getNextSwitchCase()) { assert(LabelAndGotoScopes.count(SC) && "Case not visited?"); CheckJump(SS, SC, SC->getLocStart(), diag::err_switch_into_protected_scope); } continue; } unsigned DiagnosticScope; // We don't know where an indirect goto goes, require that it be at the // top level of scoping. if (IndirectGotoStmt *IG = dyn_cast<IndirectGotoStmt>(Jump)) { assert(LabelAndGotoScopes.count(Jump) && "Jump didn't get added to scopes?"); unsigned GotoScope = LabelAndGotoScopes[IG]; if (GotoScope == 0) continue; // indirect jump is ok. S.Diag(IG->getGotoLoc(), diag::err_indirect_goto_in_protected_scope); DiagnosticScope = GotoScope; } else { // We model &&Label as a jump for purposes of scope tracking. We actually // don't care *where* the address of label is, but we require the *label // itself* to be in scope 0. If it is nested inside of a VLA scope, then // it is possible for an indirect goto to illegally enter the VLA scope by // indirectly jumping to the label. assert(isa<AddrLabelExpr>(Jump) && "Unknown jump type"); LabelStmt *TheLabel = cast<AddrLabelExpr>(Jump)->getLabel(); assert(LabelAndGotoScopes.count(TheLabel) && "Referenced label didn't get added to scopes?"); unsigned LabelScope = LabelAndGotoScopes[TheLabel]; if (LabelScope == 0) continue; // Addr of label is ok. S.Diag(Jump->getLocStart(), diag::err_addr_of_label_in_protected_scope); DiagnosticScope = LabelScope; } // Report all the things that would be skipped over by this &&label or // indirect goto. while (DiagnosticScope != 0) { S.Diag(Scopes[DiagnosticScope].Loc, Scopes[DiagnosticScope].Diag); DiagnosticScope = Scopes[DiagnosticScope].ParentScope; } } }
bool VisitStmt(Stmt *s) { // Fill out this function for your homework SourceManager &srcmgr = *m_srcmgr; SourceLocation startLoc = s->getLocStart(); unsigned int lineNum = srcmgr.getExpansionLineNumber(startLoc); unsigned int colNum = srcmgr.getExpansionColumnNumber(startLoc); /*string filename = srcmgr.getFilename(startLoc); if ((!filename.compare("")) || filename.com) { filename = prevFilename; } else { prevFilename = filename; }*/ if (isa<IfStmt>(s)) { printBranchLineColFilename("If", lineNum, colNum, filename); IfStmt *ifstmt = cast<IfStmt>(s); if(!ifstmt->getElse()) cout<<"this \"if\" has no else"<<endl; else ifstmt->getElse()->dumpColor(); } else if (isa<ForStmt>(s)) { printBranchLineColFilename("For", lineNum, colNum, filename); } else if (isa<WhileStmt>(s)) { printBranchLineColFilename("While", lineNum, colNum, filename); } else if (isa<CaseStmt>(s)) { printBranchLineColFilename("Case", lineNum, colNum, filename); } else if (isa<DoStmt>(s)) { //s->dump(); printBranchLineColFilename("Do", lineNum, colNum, filename); } else if (isa<DefaultStmt>(s)) { printBranchLineColFilename("Default", lineNum, colNum, filename); } else if (isa<ConditionalOperator>(s)) { printBranchLineColFilename("?:", lineNum, colNum, filename); } else if (isa<SwitchStmt>(s)) { SwitchStmt *switchstmt = cast<SwitchStmt>(s); SwitchCase *branch = switchstmt->getSwitchCaseList(); bool hasDefault = false; for(; branch != NULL ; branch = branch->getNextSwitchCase()) { if (isa<DefaultStmt>(branch)) { hasDefault = true; break; } } if(!hasDefault) printBranchLineColFilename("ImpDef", lineNum, colNum, filename); } return true; }
bool VisitSwitchStmt(SwitchStmt *switchStmt) { // SwitchCaseList has a linked data structure in the reversed order SwitchCase *currentSwitchCase = switchStmt->getSwitchCaseList(); while (currentSwitchCase && isa<CaseStmt>(currentSwitchCase)) { SwitchCase *nextSwitchCase = currentSwitchCase->getNextSwitchCase(); if (nextSwitchCase && isa<DefaultStmt>(nextSwitchCase)) { addViolation(nextSwitchCase, this); } currentSwitchCase = nextSwitchCase; } return true; }
/// VerifyJumps - Verify each element of the Jumps array to see if they are /// valid, emitting diagnostics if not. void JumpScopeChecker::VerifyJumps() { while (!Jumps.empty()) { Stmt *Jump = Jumps.pop_back_val(); // With a goto, if (GotoStmt *GS = dyn_cast<GotoStmt>(Jump)) { // The label may not have a statement if it's coming from inline MS ASM. if (GS->getLabel()->getStmt()) { CheckJump(GS, GS->getLabel()->getStmt(), GS->getGotoLoc(), diag::err_goto_into_protected_scope, diag::ext_goto_into_protected_scope, diag::warn_cxx98_compat_goto_into_protected_scope); } CheckGotoStmt(GS); continue; } // We only get indirect gotos here when they have a constant target. if (IndirectGotoStmt *IGS = dyn_cast<IndirectGotoStmt>(Jump)) { LabelDecl *Target = IGS->getConstantTarget(); CheckJump(IGS, Target->getStmt(), IGS->getGotoLoc(), diag::err_goto_into_protected_scope, diag::ext_goto_into_protected_scope, diag::warn_cxx98_compat_goto_into_protected_scope); continue; } SwitchStmt *SS = cast<SwitchStmt>(Jump); for (SwitchCase *SC = SS->getSwitchCaseList(); SC; SC = SC->getNextSwitchCase()) { if (CHECK_PERMISSIVE(!LabelAndGotoScopes.count(SC))) continue; SourceLocation Loc; if (CaseStmt *CS = dyn_cast<CaseStmt>(SC)) Loc = CS->getLocStart(); else if (DefaultStmt *DS = dyn_cast<DefaultStmt>(SC)) Loc = DS->getLocStart(); else Loc = SC->getLocStart(); CheckJump(SS, SC, Loc, diag::err_switch_into_protected_scope, 0, diag::warn_cxx98_compat_switch_into_protected_scope); } } }
bool VisitSwitchStmt(SwitchStmt *switchStmt) { SwitchCase *currentSwitchCase = switchStmt->getSwitchCaseList(); bool hasDefault = false; while (currentSwitchCase) { if (isa<DefaultStmt>(currentSwitchCase)) { hasDefault = true; break; } currentSwitchCase = currentSwitchCase->getNextSwitchCase(); } if (hasDefault && switchStmt->isAllEnumCasesCovered()) { addViolation(switchStmt, this); } return true; }
Stmt *TransformVector::VisitSwitchStmt(SwitchStmt *Node) { DeclVector DeclVec; // Cond Expr *Cond = Node->getCond(); if (Cond->getType()->isVectorType()) { Node->setCond(ConvertVecLiteralInExpr(DeclVec, Cond)); } else { Node->setCond(TransformExpr(Cond)); } // Body Stmt *Body = Node->getBody(); CompoundStmt *CS = dyn_cast<CompoundStmt>(Body); if (!CS) { // Convert a single stmt body into a CompoundStmt. SourceLocation loc; CS = new (ASTCtx) CompoundStmt(ASTCtx, &Body, 1, loc, loc); } // Check all SwitchCase stmts themselves. SwitchCase *CurCase = Node->getSwitchCaseList(); while (CurCase) { if (CaseStmt *CaseS = dyn_cast<CaseStmt>(CurCase)) { Expr *CaseLHS = CaseS->getLHS(); if (CaseLHS->getType()->isVectorType()) { CaseS->setLHS(ConvertVecLiteralInExpr(DeclVec, CaseLHS)); } else { CaseS->setLHS(TransformExpr(CaseLHS)); } Expr *CaseRHS = CaseS->getRHS(); if (CaseRHS && CaseRHS->getType()->isVectorType()) { CaseS->setRHS(ConvertVecLiteralInExpr(DeclVec, CaseRHS)); } else { CaseS->setRHS(TransformExpr(CaseRHS)); } } CurCase = CurCase->getNextSwitchCase(); } // Check if there was a vector literal code motion. if (DeclVec.size() > 0) { PushBackDeclStmts(*CurStmtVec, DeclVec); } // If case stmts are not CompoundStmts, convert them into CompoundStmts StmtVector BodyStmts; CompoundStmt::body_iterator I, E; for (I = CS->body_begin(), E = CS->body_end(); I != E; ++I) { // Save the current stmt BodyStmts.push_back(*I); if (SwitchCase *SC = dyn_cast<SwitchCase>(*I)) { CompoundStmt::body_iterator NextI = I + 1; if (NextI == E) break; if (isa<SwitchCase>(*NextI)) { // No stmt between current case stmt and next case stmt. if (Stmt *SubStmt = SC->getSubStmt()) { if (!isa<CompoundStmt>(SubStmt)) { SourceLocation loc; CompoundStmt *SubCS = new (ASTCtx) CompoundStmt(ASTCtx, &SubStmt, 1, loc, loc); if (CaseStmt *CaseS = dyn_cast<CaseStmt>(SC)) { CaseS->setSubStmt(SubCS); } else if (DefaultStmt *DefaultS = dyn_cast<DefaultStmt>(SC)) { DefaultS->setSubStmt(SubCS); } else { assert(0 && "What statement?"); } } } } else { StmtVector StmtVec; // SubStmt if (Stmt *SubStmt = SC->getSubStmt()) { StmtVec.push_back(SubStmt); } // Following stmts do { I = NextI; StmtVec.push_back(*I); } while ((++NextI != E) && !isa<SwitchCase>(*NextI)); // Convert all stmts into a CompoundStmt. SourceLocation loc; CompoundStmt *SubCS = new (ASTCtx) CompoundStmt(ASTCtx, StmtVec.data(), StmtVec.size(), loc, loc); if (CaseStmt *CaseS = dyn_cast<CaseStmt>(SC)) { CaseS->setSubStmt(SubCS); } else if (DefaultStmt *DefaultS = dyn_cast<DefaultStmt>(SC)) { DefaultS->setSubStmt(SubCS); } else { assert(0 && "What statement?"); } } } //end if } //end for CS = new (ASTCtx) CompoundStmt(ASTCtx, BodyStmts.data(), BodyStmts.size(), SourceLocation(), SourceLocation()); ASTCtx.Deallocate(Node->getBody()); Node->setBody(TransformStmt(CS)); return Node; }
///search the function body for call-log pairs void FindPatternVisitor::travelStmt(Stmt *stmt, Stmt *father){ if(!stmt || !father) return; ///Function return error (include Invalid input check) ///find if(foo()), stmt is located in the condexpr of ifstmt if(IfStmt *ifStmt = dyn_cast<IfStmt>(father)){ if(ifStmt->getCond() == stmt){ if(CallExpr *callExpr = searchCall(stmt)){ if(isLibFunction(callExpr)) searchLog(callExpr, father); } } } ///find switch(foo()), stmt is located in the condexpr of switchstmt if(SwitchStmt *switchStmt = dyn_cast<SwitchStmt>(father)){ if(switchStmt->getCond() == stmt){ if(CallExpr *callExpr = searchCall(stmt)){ if(isLibFunction(callExpr)) searchLog(callExpr, father); } } } ///find 'ret = foo()', when stmt = 'BinaryOperator', op == '=' and RHS == 'callexpr' if(BinaryOperator *binaryOperator = dyn_cast<BinaryOperator>(stmt)){ if(binaryOperator->getOpcode() == BO_Assign){ if(Expr *expr = binaryOperator->getRHS()){ expr = expr->IgnoreImpCasts(); expr = expr->IgnoreImplicit(); expr = expr->IgnoreParens(); if(CallExpr *callExpr = dyn_cast<CallExpr>(expr)){ if(isLibFunction(callExpr)){ bool isYoungBrother = false; for(Stmt::child_iterator bro = father->child_begin(); bro != father->child_end(); ++bro){ if(Stmt *brother = *bro){ if(brother == stmt){ isYoungBrother = true; continue; } if(isYoungBrother == false){ continue; } searchLog(callExpr, brother); break; } } } } } } } ///Unexpected cases falling into default if(SwitchStmt *switchStmt = dyn_cast<SwitchStmt>(stmt)){ SwitchCase *switchCase = switchStmt->getSwitchCaseList(); while(1){ if(!switchCase) break; if(DefaultStmt *defaultStmt = dyn_cast<DefaultStmt>(switchCase)){ searchLog("SwitchDefault", defaultStmt); break; } switchCase = switchCase->getNextSwitchCase(); } } ///Failed memory safety check if(BinaryOperator *binaryOperator = dyn_cast<BinaryOperator>(stmt)){ if(binaryOperator->getOpcode() == BO_Assign){ if(Expr *expr = binaryOperator->getRHS()){ expr = expr->IgnoreImpCasts(); expr = expr->IgnoreImplicit(); expr = expr->IgnoreParens(); if(CallExpr *callExpr = dyn_cast<CallExpr>(expr)){ string returnName = expr2str(binaryOperator->getLHS()); bool isYoungBrother = false; for(Stmt::child_iterator bro = father->child_begin(); bro != father->child_end(); ++bro){ if(Stmt *brother = *bro){ if(brother == stmt){ isYoungBrother = true; continue; } if(isYoungBrother == false){ continue; } if(IfStmt *ifStmt = dyn_cast<IfStmt>(brother)){ string ifCond = expr2str(ifStmt->getCond()); if(ifCond.find(returnName) != string::npos && (ifCond.find("null") != string::npos || ifCond.find("NULL") != string::npos)) searchLog(callExpr, brother); } break; } } } } } } for(Stmt::child_iterator it = stmt->child_begin(); it != stmt->child_end(); ++it){ if(Stmt *child = *it) travelStmt(child, stmt); } return; }