Exemple #1
0
/// 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;
    }
  }
}
Exemple #4
0
 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;
    }
Exemple #6
0
/// 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;
}