예제 #1
0
파일: qdeleteall.cpp 프로젝트: nimxor/clazy
void QDeleteAll::VisitStmt(clang::Stmt *stmt)
{
    // Find a call to QMap/QSet/QHash::values
    CXXMemberCallExpr *valuesCall = dyn_cast<CXXMemberCallExpr>(stmt);
    if (valuesCall &&
        valuesCall->getDirectCallee() &&
        valuesCall->getDirectCallee()->getNameAsString() == "values")
    {
        const std::string valuesClassName = valuesCall->getMethodDecl()->getParent()->getNameAsString();
        if (valuesClassName == "QMap" || valuesClassName == "QSet" || valuesClassName == "QHash") { // QMultiHash and QMultiMap automatically supported
            // Once found see if the first parent call is qDeleteAll
            int i = 1;
            Stmt *p = Utils::parent(m_parentMap, stmt, i);
            while (p) {
                CallExpr *pc = dyn_cast<CallExpr>(p);
                if (pc) {
                    if (pc->getDirectCallee() && pc->getDirectCallee()->getNameAsString() == "qDeleteAll") {
                        emitWarning(p->getLocStart(), "Calling qDeleteAll with " + valuesClassName + "::values, call qDeleteAll on the container itself");
                    }
                    break;
                }
                ++i;
                p = Utils::parent(m_parentMap, stmt, i);
            }
        }
    }
}
예제 #2
0
bool CursorHelper::isCursorDeclaredInCurrentFile(CXCursor node)
{
  FileID fileId;
  Decl *decl = CursorHelper::getDecl(node);
  Stmt *stmt = CursorHelper::getStmt(node);
  if (decl)
  {
    fileId =
      CursorHelper::getASTContext(node)
        .getSourceManager()
        .getFileID(decl->getLocation());
  }
  else if (stmt)
  {
    fileId =
      CursorHelper::getASTContext(node)
        .getSourceManager()
        .getFileID(stmt->getLocStart());
  }
  else
  {
    return false;
  }
  SourceLocation sourceLocation =
    CursorHelper::getASTContext(node).getSourceManager().getIncludeLoc(fileId);
  return sourceLocation.isInvalid();
}
예제 #3
0
 /*! Visit Statement \p s. */
 bool VisitStmt(Stmt *s) {
     // Only care about If statements.
     if (isa<IfStmt>(s)) {
         IfStmt *IfStatement = cast<IfStmt>(s);
         Stmt *Then = IfStatement->getThen();
         m_rw.InsertText(Then->getLocStart(),
                                "// the 'if' part\n",
                                true, true);
         Stmt *Else = IfStatement->getElse();
         if (Else)
             m_rw.InsertText(Else->getLocStart(),
                                    "// the 'else' part\n",
                                    true, true);
     }
     return true;
 }
예제 #4
0
void FakeDirectiveHandler::InsertAccess(Expr * Current,
                                    DeclRefExpr * Original,
                                    bool Write,
                                    vector<LocalStmtPair> WritePairs,
                                    bool ActualVar,
                                    string Struct) {

  if (!ActualVar) return;
  
  const Type * T = Current->getType().getTypePtr();
  
  if (FullDirectives->IsPrivate(Original, Struct, T, Original->getLocStart())) {
    return;
  }

  vector<LocalStmtPair>::iterator it;

  CompilerInstance &CI = FullDirectives->GetCI(Current->getLocStart());

  for (it = WritePairs.begin(); it != WritePairs.end(); it++) {
  
    bool insertAfter = it->insertAfter;
    Stmt * curStmt = it->stmt;

    bool isBracket = false;

    SourceLocation start = curStmt->getLocStart();
    SourceLocation end = FindSemiAfterLocation(curStmt->getLocEnd(),
                                               CI.getASTContext());

    if (end.isInvalid()) {
      end = curStmt->getLocEnd();
      isBracket = true;
    }
    
    SourceLocation loc;
    
    if (insertAfter) {
      if (isBracket) {
        loc = end;
      } else {
        loc = end.getLocWithOffset(1);
      }
    } else {
      loc = start;
    }
    
    loc = tools::UnpackMacroLoc(loc, CI);

    if (GetOrSetAccessed(loc, Current, Write)) {
      continue;
    }

    FullDirectives->InsertDeclAccess(Original->getFoundDecl(), Write);

  }

}
/// 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;
    }
  }
}
예제 #6
0
bool ReserveCandidates::isInComplexLoop(clang::Stmt *s, SourceLocation declLocation, bool isMemberVariable) const
{
    if (!s || declLocation.isInvalid())
        return false;

    int forCount = 0;
    int foreachCount = 0;

    static vector<unsigned int> nonComplexOnesCache;
    static vector<unsigned int> complexOnesCache;
    auto rawLoc = s->getLocStart().getRawEncoding();


    // For some reason we generate two warnings on some foreaches, so cache the ones we processed
    // and return true so we don't trigger a warning
    if (clazy_std::contains(nonComplexOnesCache, rawLoc) || clazy_std::contains(complexOnesCache, rawLoc))
        return true;

    Stmt *parent = s;
    PresumedLoc lastForeachForStm;
    while ((parent = HierarchyUtils::parent(m_parentMap, parent))) {
        const SourceLocation parentStart = parent->getLocStart();
        if (!isMemberVariable && sm().isBeforeInSLocAddrSpace(parentStart, declLocation)) {
            nonComplexOnesCache.push_back(rawLoc);
            return false;
        }

        bool isLoop = false;
        if (loopIsComplex(parent, isLoop)) {
            complexOnesCache.push_back(rawLoc);
            return true;
        }

        if (QtUtils::isInForeach(m_ci, parentStart)) {
            auto ploc = sm().getPresumedLoc(parentStart);
            if (Utils::presumedLocationsEqual(ploc, lastForeachForStm)) {
                // Q_FOREACH comes in pairs, because each has two for statements inside, so ignore one when counting
            } else {
                foreachCount++;
                lastForeachForStm = ploc;
            }
        } else {
            if (isLoop)
                forCount++;
        }

        if (foreachCount > 1 || forCount > 1) { // two foreaches are almost always a false-positve
            complexOnesCache.push_back(rawLoc);
            return true;
        }


    }

    nonComplexOnesCache.push_back(rawLoc);
    return false;
}
예제 #7
0
void SimpleInliner::copyFunctionBody(void)
{
  Stmt *Body = CurrentFD->getBody();
  TransAssert(Body && "NULL Body!");

  std::string FuncBodyStr("");
  RewriteHelper->getStmtString(Body, FuncBodyStr);
  TransAssert(FuncBodyStr[0] == '{');

  SourceLocation StartLoc = Body->getLocStart();
  const char *StartBuf = SrcManager->getCharacterData(StartLoc);

  std::vector< std::pair<ReturnStmt *, int> > SortedReturnStmts;
  sortReturnStmtsByOffs(StartBuf, SortedReturnStmts);

  // Now we start rewriting
  int Delta = 1; // skip the first { symbol
  FuncBodyStr.insert(Delta, "\n");
  ++Delta;
  for(SmallVector<std::string, 10>::iterator I = ParmStrings.begin(),
       E = ParmStrings.end(); I != E; ++I) {
    std::string PStr = (*I);
    FuncBodyStr.insert(Delta, PStr);
    Delta += PStr.size();
  }

  // restore the effect of {
  Delta--;
  int ReturnSZ = 6;
  std::string TmpVarStr = TmpVarName + " = ";
  int TmpVarNameSize = static_cast<int>(TmpVarStr.size());

  for(std::vector< std::pair<ReturnStmt *, int> >::iterator
      I = SortedReturnStmts.begin(), E = SortedReturnStmts.end(); 
      I != E; ++I) {

    ReturnStmt *RS = (*I).first;
    int Off = (*I).second + Delta;
    Expr *Exp = RS->getRetValue();
    if (Exp) {
      const Type *T = Exp->getType().getTypePtr();
      if (!T->isVoidType()) {
        FuncBodyStr.replace(Off, ReturnSZ, TmpVarStr);
        Delta += (TmpVarNameSize - ReturnSZ);
        continue;
      }
    }
    FuncBodyStr.replace(Off, ReturnSZ, "");
    Delta -= ReturnSZ;
  }

  RewriteHelper->addStringBeforeStmt(TheStmt, FuncBodyStr, NeedParen);
}
예제 #8
0
bool RewriteUtils::addLocalVarToFunc(const std::string &VarStr,
                                     FunctionDecl *FD)
{
  Stmt *Body = FD->getBody();
  TransAssert(Body && "NULL body for a function definition!");

  std::string IndentStr;
  StmtIterator I = Body->child_begin();

  if (I == Body->child_end())
    IndentStr = DefaultIndentStr;
  else
    IndentStr = getStmtIndentString((*I), SrcManager);

  std::string NewVarStr = "\n" + IndentStr + VarStr;
  SourceLocation StartLoc = Body->getLocStart();
  return !(TheRewriter->InsertTextAfterToken(StartLoc, NewVarStr));
}
예제 #9
0
// TODO: Handle call expr? Still need this for reads of params etc.
bool FakeDirectiveHandler::VisitDeclRefExpr(DeclRefExpr *S) {

  if (WaitingHeader && IsChild(S, WaitingHeader)) {
    return true;
  }

  FunctionDecl * F = dyn_cast<FunctionDecl>(S->getDecl());
  
  if (F) {
    return true;
  }
  
  SourceManager &SM = FullDirectives->GetCI(S->getLocStart()).getSourceManager();

  // TODO: Replace with presumed loc stuff
  SourceLocation Loc = tools::GetNearestValidLoc(S, SM, PM);

  if (FullDirectives->IsCompletelyPrivate(S, Loc)) {
    return true;
  }

  Expr * Var = getVar(S);
  Stmt * Base = getBase(S);
  Stmt * Parent = getParent(Base);

  Stmt * Top;
  
  if (!Parent || FullDirectives->IsLocDirectlyAfterPragma(Parent->getLocStart())) {
    Top = FullDirectives->GetHeader(S->getLocStart());
  } else {
    Top = Parent;
  }

  vector<LocalStmtPair> WritePairs = GenerateWritePairs(Base, Parent, Top);
  
  WalkUpExpr(S, Var, WritePairs, true, string());
  
  return true;
  
}
예제 #10
0
    virtual bool VisitFunctionDecl(FunctionDecl *func) {
        NameCodeMap::const_iterator iterator;
        for (iterator = functionsMap.begin(); iterator != functionsMap.end(); ++iterator) {
            string currentFunctionName = func->getNameInfo().getName().getAsString();
            // TODO: additional checkups


            if(func->isThisDeclarationADefinition() && iterator->first.compare(currentFunctionName)==0){
                // std::cout<<"current function: "<<currentFunctionName<<" lookedup func: "<<iterator->first<<std::endl;
                SourceLocation currentLocation;

                Stmt * definition = func->getBody();
                for (StmtRange range = definition->children(); range; ++range){
                    Stmt * fs = *range;
                    currentLocation = fs->getLocStart();
                    break;
                }
                rewriter.InsertTextBefore(currentLocation,functionsMap[iterator->first]);
            }
        }
        return true;
    }
예제 #11
0
bool AnalysisDeclContext::isBodyAutosynthesizedFromModelFile() const {
  bool Tmp;
  Stmt *Body = getBody(Tmp);
  return Tmp && Body->getLocStart().isValid();
}