bool VisitSwitchStmt(SwitchStmt *switchStmt)
    {
        CompoundStmt *compoundStmt = dyn_cast_or_null<CompoundStmt>(switchStmt->getBody());
        if (compoundStmt)
        {
            bool breakFound = true;
            for (CompoundStmt::body_iterator body = compoundStmt->body_begin(),
                bodyEnd = compoundStmt->body_end(); body != bodyEnd; body++)
            {
                Stmt *bodyStmt = dyn_cast<Stmt>(*body);
                if (isBreakingPoint(bodyStmt))
                {
                    breakFound = true;
                    continue;
                }
                if (isSwitchCase(bodyStmt))
                {
                    if (!breakFound)
                    {
                        addViolation(switchStmt, this);
                        break;
                    }

                    FindingBreak findingBreak;
                    breakFound = findingBreak.findBreak(dyn_cast<SwitchCase>(bodyStmt));
                }
            }
            if (!breakFound)
            {
                addViolation(switchStmt, this);
            }
        }

        return true;
    }
Esempio n. 2
0
Stmt *TransformVector::VisitDoStmt(DoStmt *Node) {
  // Body
  Stmt *Body = Node->getBody();
  CompoundStmt *CS = dyn_cast<CompoundStmt>(Body);
  if (!CS) {
    // Convert a single stmt Body into a compound stmt.
    SourceLocation loc;
    CS = new (ASTCtx) CompoundStmt(ASTCtx, &Body, 1, loc, loc);
  }
  Node->setBody(TransformStmt(CS));

  // Cond
  Expr *Cond = Node->getCond();
  if (Cond->getType()->isVectorType()) {
    DeclVector DeclVec;
    Node->setCond(ConvertVecLiteralInExpr(DeclVec, Cond));

    if (DeclVec.size() > 0) {
      CS = dyn_cast<CompoundStmt>(Node->getBody());

      StmtVector StmtVec;
      CompoundStmt::body_iterator I, E;
      for (I = CS->body_begin(), E = CS->body_end(); I != E; ++I) {
        StmtVec.push_back(*I);
      }
      PushBackDeclStmts(StmtVec, DeclVec);

      CS->setStmts(ASTCtx, StmtVec.data(), StmtVec.size());
    }
  } else {
    Node->setCond(TransformExpr(Cond));
  }

  return Node;
}
Esempio n. 3
0
void UnreachableCodeRule::apply(
  CXCursor& node, CXCursor& parentNode, ViolationSet& violationSet)
{
  Stmt *stmt = CursorHelper::getStmt(node);
  if (stmt)
  {
    CompoundStmt *compoundStmt = dyn_cast<CompoundStmt>(stmt);
    if (compoundStmt)
    {
      bool hasBreakPoint = false;
      for (CompoundStmt::body_iterator body = compoundStmt->body_begin(),
        bodyEnd = compoundStmt->body_end();
        body != bodyEnd;
        body++)
      {
        if (hasBreakPoint)
        {
          Violation violation(node, this);
          violationSet.addViolation(violation);
          return;
        }
        else
        {
          Stmt *bodyStmt = (Stmt *)*body;
          hasBreakPoint = isBreakPoint(bodyStmt, parentNode);
        }
      }
    }
  }
}
Esempio n. 4
0
/// EmitCompoundStmt - Emit a compound statement {..} node.  If GetLast is true,
/// this captures the expression result of the last sub-statement and returns it
/// (for use by the statement expression extension).
RValue CodeGenFunction::EmitCompoundStmt(const CompoundStmt &S, bool GetLast,
                                         llvm::Value *AggLoc, bool isAggVol) {
  PrettyStackTraceLoc CrashInfo(getContext().getSourceManager(),S.getLBracLoc(),
                             "LLVM IR generation of compound statement ('{}')");
  
  CGDebugInfo *DI = getDebugInfo();
  if (DI) {
    EnsureInsertPoint();
    DI->setLocation(S.getLBracLoc());
    // FIXME: The llvm backend is currently not ready to deal with region_end
    // for block scoping.  In the presence of always_inline functions it gets so
    // confused that it doesn't emit any debug info.  Just disable this for now.
    //DI->EmitRegionStart(CurFn, Builder);
  }

  // Keep track of the current cleanup stack depth.
  size_t CleanupStackDepth = CleanupEntries.size();
  bool OldDidCallStackSave = DidCallStackSave;
  DidCallStackSave = false;
  
  for (CompoundStmt::const_body_iterator I = S.body_begin(),
       E = S.body_end()-GetLast; I != E; ++I)
    EmitStmt(*I);

  if (DI) {
    EnsureInsertPoint();
    DI->setLocation(S.getRBracLoc());
    
    // FIXME: The llvm backend is currently not ready to deal with region_end
    // for block scoping.  In the presence of always_inline functions it gets so
    // confused that it doesn't emit any debug info.  Just disable this for now.
    //DI->EmitRegionEnd(CurFn, Builder);
  }

  RValue RV;
  if (!GetLast) 
    RV = RValue::get(0);
  else {
    // We have to special case labels here.  They are statements, but when put 
    // at the end of a statement expression, they yield the value of their
    // subexpression.  Handle this by walking through all labels we encounter,
    // emitting them before we evaluate the subexpr.
    const Stmt *LastStmt = S.body_back();
    while (const LabelStmt *LS = dyn_cast<LabelStmt>(LastStmt)) {
      EmitLabel(*LS);
      LastStmt = LS->getSubStmt();
    }
  
    EnsureInsertPoint();
    
    RV = EmitAnyExpr(cast<Expr>(LastStmt), AggLoc);
  }

  DidCallStackSave = OldDidCallStackSave;
  
  EmitCleanupBlocks(CleanupStackDepth);
  
  return RV;
}
NamedDecl* RedundantLocalVariableRule::extractFromDeclStmt(Stmt *stmt) {
  CompoundStmt *compoundStmt = dyn_cast<CompoundStmt>(stmt);
  if (compoundStmt && compoundStmt->size() >= 2) {
    Stmt *lastSecondStmt = (Stmt *)*(compoundStmt->body_end() - 2);
    DeclStmt *declStmt = dyn_cast<DeclStmt>(lastSecondStmt);
    if (declStmt && declStmt->isSingleDecl()) {
      return dyn_cast<NamedDecl>(declStmt->getSingleDecl());
    }
  }
  return NULL;
}
Esempio n. 6
0
bool RNFStatementVisitor::VisitStmtExpr(StmtExpr *SE)
{
  CompoundStmt *CS = SE->getSubStmt();
  if (ConsumerInstance->CallExprQueue.empty()) {
    TraverseStmt(CS);
    return false;
  }

  CallExpr *CallE = ConsumerInstance->CallExprQueue.back();
  CurrentStmt = CallE;

  for (clang::CompoundStmt::body_iterator I = CS->body_begin(),
       E = CS->body_end(); I != E; ++I) {
    TraverseStmt(*I);
  }
  return false;
}
Esempio n. 7
0
int NPathComplexityMetric::nPath(SwitchStmt *stmt)
{
    int internalNPath = 0, nPathSwitchStmt = nPath(stmt->getCond());
    CompoundStmt *body = (CompoundStmt *)stmt->getBody();
    for (CompoundStmt::body_iterator bodyStmt = body->body_begin(), bodyStmtEnd = body->body_end();
        bodyStmt != bodyStmtEnd; bodyStmt++)
    {
        if (isa<SwitchCase>(*bodyStmt))
        {
            SwitchCase *switchCase = dyn_cast<SwitchCase>(*bodyStmt);
            nPathSwitchStmt += internalNPath;
            internalNPath = nPath(switchCase->getSubStmt());
        }
        else
        {
            internalNPath *= nPath(*bodyStmt);
        }
    }
    return nPathSwitchStmt + internalNPath;
}
Esempio n. 8
0
  bool DeclExtractor::ExtractDecl(FunctionDecl* FD) {
    llvm::SmallVector<NamedDecl*, 4> TouchedDecls;
    CompoundStmt* CS = dyn_cast<CompoundStmt>(FD->getBody());
    assert(CS && "Function body not a CompoundStmt?");
    DeclContext* DC = FD->getTranslationUnitDecl();
    Scope* TUScope = m_Sema->TUScope;
    assert(TUScope == m_Sema->getScopeForContext(DC) && "TU scope from DC?");
    llvm::SmallVector<Stmt*, 4> Stmts;

    for (CompoundStmt::body_iterator I = CS->body_begin(), EI = CS->body_end();
         I != EI; ++I) {
      DeclStmt* DS = dyn_cast<DeclStmt>(*I);
      if (!DS) {
        Stmts.push_back(*I);
        continue;
      }
      
      for (DeclStmt::decl_iterator J = DS->decl_begin();
           J != DS->decl_end(); ++J) {
        NamedDecl* ND = dyn_cast<NamedDecl>(*J);
        if (isa<UsingDirectiveDecl>(*J))
          continue; // FIXME: Here we should be more elegant.
        if (ND) {
          if (Stmts.size()) {
            // We need to emit a new custom wrapper wrapping the stmts
            EnforceInitOrder(Stmts);
            assert(!Stmts.size() && "Stmt list must be flushed.");
          }

          // We know the transaction is closed, but it is safe.
          getTransaction()->forceAppend(ND);

          DeclContext* OldDC = ND->getDeclContext();

          // Make sure the decl is not found at its old possition
          ND->getLexicalDeclContext()->removeDecl(ND);
          if (Scope* S = m_Sema->getScopeForContext(OldDC)) {
            S->RemoveDecl(ND);
            if (utils::Analyze::isOnScopeChains(ND, *m_Sema))
              m_Sema->IdResolver.RemoveDecl(ND);
          }

          // For variable definitions causing var/function ambiguity such as:
          // MyClass my();, C++ standard says it shall be resolved as a function
          //
          // In the particular context this definition is inside a function
          // already, but clang thinks it as a lambda, so we need to ignore the
          // check decl context vs lexical decl context.
          if (ND->getDeclContext() == ND->getLexicalDeclContext()
              || isa<FunctionDecl>(ND))
            ND->setLexicalDeclContext(DC);
          else 
            assert(0 && "Not implemented: Decl with different lexical context");
          ND->setDeclContext(DC);

          if (VarDecl* VD = dyn_cast<VarDecl>(ND)) {
            VD->setStorageClass(SC_None);
          }

          clearLinkage(ND);

          TouchedDecls.push_back(ND);
        }
      }
    }
    bool hasNoErrors = !CheckForClashingNames(TouchedDecls, DC, TUScope);
    if (hasNoErrors) {
      for (size_t i = 0; i < TouchedDecls.size(); ++i) {
        // We should skip the checks for annonymous decls and we should not
        // register them in the lookup.
        if (!TouchedDecls[i]->getDeclName())
          continue;

        m_Sema->PushOnScopeChains(TouchedDecls[i],
                                  m_Sema->getScopeForContext(DC),
                    /*AddCurContext*/!isa<UsingDirectiveDecl>(TouchedDecls[i]));

        // The transparent DeclContexts (eg. scopeless enum) doesn't have 
        // scopes. While extracting their contents we need to update the
        // lookup tables and telling them to pick up the new possitions
        // in the AST.
        if (DeclContext* InnerDC = dyn_cast<DeclContext>(TouchedDecls[i])) {
          if (InnerDC->isTransparentContext()) {
            // We can't PushDeclContext, because we don't have scope.
            Sema::ContextRAII pushedDC(*m_Sema, InnerDC);

            for(DeclContext::decl_iterator DI = InnerDC->decls_begin(), 
                  DE = InnerDC->decls_end(); DI != DE ; ++DI) {
              if (NamedDecl* ND = dyn_cast<NamedDecl>(*DI))
                InnerDC->makeDeclVisibleInContext(ND);
            }
          }
        }
      }
    }

    CS->setStmts(*m_Context, Stmts.data(), Stmts.size());

    // The order matters, because when we extract decls from the wrapper we
    // append them to the transaction. If the transaction gets unloaded it will
    // introduce a fake dependency, so put the move last.
    Transaction* T = getTransaction();
    for (Transaction::iterator I = T->decls_begin(), E = T->decls_end();
         I != E; ++I)
      if (!I->m_DGR.isNull() && I->m_DGR.isSingleDecl()
          && I->m_DGR.getSingleDecl() == T->getWrapperFD()) {
        T->erase(I);
        break;
      }
    T->forceAppend(FD);

    // Put the wrapper after its declarations. (Nice when AST dumping)
    DC->removeDecl(FD);
    DC->addDecl(FD);

    return hasNoErrors;
  }
Esempio n. 9
0
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;
}
Esempio n. 10
0
  bool DeclExtractor::ExtractDecl(Decl* D) {
    FunctionDecl* FD = dyn_cast<FunctionDecl>(D);

    if (FD) {
      if (FD->getNameAsString().find("__cling_Un1Qu3"))
        return true;

      llvm::SmallVector<NamedDecl*, 4> TouchedDecls;
      CompoundStmt* CS = dyn_cast<CompoundStmt>(FD->getBody());
      assert(CS && "Function body not a CompoundStmt?");
      DeclContext* DC = FD->getTranslationUnitDecl();
      Scope* TUScope = m_Sema->TUScope;
      assert(TUScope == m_Sema->getScopeForContext(DC) && "TU scope from DC?");
      llvm::SmallVector<Stmt*, 4> Stmts;

      for (CompoundStmt::body_iterator I = CS->body_begin(), EI = CS->body_end();
           I != EI; ++I) {
        DeclStmt* DS = dyn_cast<DeclStmt>(*I);
        if (!DS) {
          Stmts.push_back(*I);
          continue;
        }

        for (DeclStmt::decl_iterator J = DS->decl_begin();
             J != DS->decl_end(); ++J) {
          NamedDecl* ND = dyn_cast<NamedDecl>(*J);
          if (ND) {
            DeclContext* OldDC = ND->getDeclContext();

            // Make sure the decl is not found at its old possition
            OldDC->removeDecl(ND);
            if (Scope* S = m_Sema->getScopeForContext(OldDC)) {
              S->RemoveDecl(ND);
              m_Sema->IdResolver.RemoveDecl(ND);
            }

            if (ND->getDeclContext() == ND->getLexicalDeclContext())
              ND->setLexicalDeclContext(DC);
            else 
              assert("Not implemented: Decl with different lexical context");
            ND->setDeclContext(DC);

            if (VarDecl* VD = dyn_cast<VarDecl>(ND)) {
              VD->setStorageClass(SC_None);
              VD->setStorageClassAsWritten(SC_None);

              // if we want to print the result of the initializer of int i = 5
              // or the default initializer int i
              if (I+1 == EI || !isa<NullStmt>(*(I+1))) {
                QualType VDTy = VD->getType().getNonReferenceType();
                Expr* DRE = m_Sema->BuildDeclRefExpr(VD, VDTy,VK_LValue,
                                                     SourceLocation()
                                                     ).take();
                Stmts.push_back(DRE);
              }
            }
            // force recalc of the linkage (to external)
            ND->ClearLinkageCache();

            TouchedDecls.push_back(ND);
          }
        }
      }
      bool hasNoErrors = !CheckForClashingNames(TouchedDecls, DC, TUScope);
      if (hasNoErrors) {
        for (size_t i = 0; i < TouchedDecls.size(); ++i) {
          m_Sema->PushOnScopeChains(TouchedDecls[i],
                                    m_Sema->getScopeForContext(DC),
                    /*AddCurContext*/!isa<UsingDirectiveDecl>(TouchedDecls[i]));

          // The transparent DeclContexts (eg. scopeless enum) doesn't have 
          // scopes. While extracting their contents we need to update the
          // lookup tables and telling them to pick up the new possitions
          //  in the AST.
          if (DeclContext* InnerDC = dyn_cast<DeclContext>(TouchedDecls[i])) {
            if (InnerDC->isTransparentContext()) {
              // We can't PushDeclContext, because we don't have scope.
              Sema::ContextRAII pushedDC(*m_Sema, InnerDC);

              for(DeclContext::decl_iterator DI = InnerDC->decls_begin(), 
                    DE = InnerDC->decls_end(); DI != DE ; ++DI) {
                if (NamedDecl* ND = dyn_cast<NamedDecl>(*DI))
                  InnerDC->makeDeclVisibleInContext(ND);
              }
            }
          }

          // Append the new top level decl to the current transaction.
          getTransaction()->appendUnique(DeclGroupRef(TouchedDecls[i]));
        }
      }

      CS->setStmts(*m_Context, Stmts.data(), Stmts.size());

      // Put the wrapper after its declarations. (Nice when AST dumping)
      DC->removeDecl(FD);
      DC->addDecl(FD);

      return hasNoErrors;
    }
    return true;
  }