コード例 #1
0
void RemoveNamespace::removeNamespace(const NamespaceDecl *ND)
{
  // Remove the right brace first
  SourceLocation StartLoc = ND->getRBraceLoc();
  if (StartLoc.isValid())
    TheRewriter.RemoveText(StartLoc, 1);

  // Then remove name and the left brace
  StartLoc = ND->getBeginLoc();
  TransAssert(StartLoc.isValid() && "Invalid Namespace LocStart!");

  const char *StartBuf = SrcManager->getCharacterData(StartLoc);
  SourceRange NDRange = ND->getSourceRange();
  SourceLocation EndLoc;
  if (NDRange.isValid()) {
    int RangeSize = TheRewriter.getRangeSize(NDRange);
    TransAssert((RangeSize != -1) && "Bad Namespace Range!");
    std::string NDStr(StartBuf, RangeSize);
    size_t Pos = NDStr.find('{');
    TransAssert((Pos != std::string::npos) && "Cannot find LBrace!");
    EndLoc = StartLoc.getLocWithOffset(Pos);
  }
  else {
    EndLoc = RewriteHelper->getEndLocationUntil(StartLoc, '{');
  }

  TheRewriter.RemoveText(SourceRange(StartLoc, EndLoc));
}
コード例 #2
0
ファイル: CXCursor.cpp プロジェクト: nicolaisi/root
CXCursor cxcursor::MakeCXCursor(const Decl *D, CXTranslationUnit TU,
                                SourceRange RegionOfInterest,
                                bool FirstInDeclGroup) {
    assert(D && TU && "Invalid arguments!");

    CXCursorKind K = getCursorKindForDecl(D);

    if (K == CXCursor_ObjCClassMethodDecl ||
            K == CXCursor_ObjCInstanceMethodDecl) {
        int SelectorIdIndex = -1;
        // Check if cursor points to a selector id.
        if (RegionOfInterest.isValid() &&
                RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
            SmallVector<SourceLocation, 16> SelLocs;
            cast<ObjCMethodDecl>(D)->getSelectorLocs(SelLocs);
            SmallVectorImpl<SourceLocation>::iterator
            I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
            if (I != SelLocs.end())
                SelectorIdIndex = I - SelLocs.begin();
        }
        CXCursor C = { K, SelectorIdIndex,
            { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }
        };
        return C;
    }

    CXCursor C = { K, 0, { D, (void*)(intptr_t) (FirstInDeclGroup ? 1 : 0), TU }};
    return C;
}
コード例 #3
0
bool ClangDocHTML::HandleComment(Preprocessor &PP, SourceRange Comment) 
{
	if(Comment.isValid()) 
	{		
		if(astConsumer->sourceManager->isInSystemHeader(Comment.getBegin()))
		{
			return false;
		}
		
		/*
		bool bInvalid = false;
		const char *cbegin = astConsumer->sourceManager->getCharacterData(Comment.getBegin(), &bInvalid);
		const char *cend = astConsumer->sourceManager->getCharacterData(Comment.getEnd(), &bInvalid);
		llvm::StringRef string = llvm::StringRef(cbegin, cend-cbegin);*/

		//Decl *decl = 0;

		/*if(string.startswith("///<"))
		{
			decl = lastDecl;
			decl->print(*Out);
		}*/

		commentsList.push_back(Comment);
		//lastComment = commentsByDecl.insert(CommentsByDeclPair(decl, string) ); 
		
		//*Out << string << "<br/>\n";
	}
	return false;
}
コード例 #4
0
/// \brief Returns a pair of [Begin, End) iterators of preprocessed entities
/// that source range \arg R encompasses.
std::pair<int, int>
PreprocessingRecord::getPreprocessedEntitiesInRangeSlow(SourceRange Range) {
  assert(Range.isValid());
  assert(!SourceMgr.isBeforeInTranslationUnit(Range.getEnd(),Range.getBegin()));
  
  std::pair<unsigned, unsigned>
    Local = findLocalPreprocessedEntitiesInRange(Range);
  
  // Check if range spans local entities.
  if (!ExternalSource || SourceMgr.isLocalSourceLocation(Range.getBegin()))
    return std::make_pair(Local.first, Local.second);
  
  std::pair<unsigned, unsigned>
    Loaded = ExternalSource->findPreprocessedEntitiesInRange(Range);
  
  // Check if range spans local entities.
  if (Loaded.first == Loaded.second)
    return std::make_pair(Local.first, Local.second);
  
  unsigned TotalLoaded = LoadedPreprocessedEntities.size();
  
  // Check if range spans loaded entities.
  if (Local.first == Local.second)
    return std::make_pair(int(Loaded.first)-TotalLoaded,
                          int(Loaded.second)-TotalLoaded);
  
  // Range spands loaded and local entities.
  return std::make_pair(int(Loaded.first)-TotalLoaded, Local.second);
}
コード例 #5
0
void RemoveUnusedOuterClass::removeOuterClass()
{
  TransAssert(TheCXXRDDef && "NULL Base CXXRD!");
  SourceLocation LocStart = TheCXXRDDef->getLocStart();
  SourceLocation LocEnd = 
    RewriteHelper->getEndLocationUntil(LocStart, '{');
  TransAssert(LocEnd.isValid() && "Invalid Location!");
  TheRewriter.RemoveText(SourceRange(LocStart, LocEnd));

  const DeclContext *Ctx = dyn_cast<DeclContext>(TheCXXRDDef);
  for (DeclContext::decl_iterator I = Ctx->decls_begin(),
       E = Ctx->decls_end(); I != E; ++I) {
    if ((*I)->isImplicit())
      continue;
    const AccessSpecDecl *AS = dyn_cast<AccessSpecDecl>(*I);
    if (!AS)
      continue;
    TheRewriter.RemoveText(AS->getSourceRange());
  }

  SourceRange BracRange = TheCXXRDDef->getBraceRange();
  TransAssert(BracRange.isValid() && "Invalid brace range!");

  TheRewriter.RemoveText(BracRange);
}
コード例 #6
0
ファイル: PathDiagnostic.cpp プロジェクト: TravisWee/clang
PathDiagnosticRange
  PathDiagnosticLocation::genRange(LocationOrAnalysisDeclContext LAC) const {
  assert(isValid());
  // Note that we want a 'switch' here so that the compiler can warn us in
  // case we add more cases.
  switch (K) {
    case SingleLocK:
      return PathDiagnosticRange(SourceRange(Loc,Loc), true);
    case RangeK:
      break;
    case StmtK: {
      const Stmt *S = asStmt();
      switch (S->getStmtClass()) {
        default:
          break;
        case Stmt::DeclStmtClass: {
          const DeclStmt *DS = cast<DeclStmt>(S);
          if (DS->isSingleDecl()) {
            // Should always be the case, but we'll be defensive.
            return SourceRange(DS->getLocStart(),
                               DS->getSingleDecl()->getLocation());
          }
          break;
        }
          // FIXME: Provide better range information for different
          //  terminators.
        case Stmt::IfStmtClass:
        case Stmt::WhileStmtClass:
        case Stmt::DoStmtClass:
        case Stmt::ForStmtClass:
        case Stmt::ChooseExprClass:
        case Stmt::IndirectGotoStmtClass:
        case Stmt::SwitchStmtClass:
        case Stmt::BinaryConditionalOperatorClass:
        case Stmt::ConditionalOperatorClass:
        case Stmt::ObjCForCollectionStmtClass: {
          SourceLocation L = getValidSourceLocation(S, LAC);
          return SourceRange(L, L);
        }
      }
      SourceRange R = S->getSourceRange();
      if (R.isValid())
        return R;
      break;  
    }
    case DeclK:
      if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D))
        return MD->getSourceRange();
      if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
        if (Stmt *Body = FD->getBody())
          return Body->getSourceRange();
      }
      else {
        SourceLocation L = D->getLocation();
        return PathDiagnosticRange(SourceRange(L, L), true);
      }
  }

  return SourceRange(Loc,Loc);
}
コード例 #7
0
void ReplaceSimpleTypedef::removeTypedefs()
{
  for (TypedefDecl::redecl_iterator I = TheTypedefDecl->redecls_begin(),
       E = TheTypedefDecl->redecls_end(); I != E; ++I) {
    SourceRange Range = (*I)->getSourceRange();
    if (Range.isValid()) {
      RewriteHelper->removeTextUntil(Range, ';');
      Rewritten = true;
    }
  }
}
コード例 #8
0
TypeRefinementContext::TypeRefinementContext(ASTContext &Ctx, IntroNode Node,
                                             TypeRefinementContext *Parent,
                                             SourceRange SrcRange,
                                             const AvailabilityContext &Info)
    : Node(Node), SrcRange(SrcRange), AvailabilityInfo(Info) {
  if (Parent) {
    assert(SrcRange.isValid());
    Parent->addChild(this);
    assert(Info.isContainedIn(Parent->getAvailabilityInfo()));
  }
  Ctx.addDestructorCleanup(Children);
}
コード例 #9
0
void ExplicitConstructorCheck::check(const MatchFinder::MatchResult &Result) {
  const CXXConstructorDecl *Ctor =
      Result.Nodes.getNodeAs<CXXConstructorDecl>("ctor");
  // Do not be confused: isExplicit means 'explicit' keyword is present,
  // isImplicit means that it's a compiler-generated constructor.
  if (Ctor->isOutOfLine() || Ctor->isImplicit() || Ctor->isDeleted() ||
      Ctor->getNumParams() == 0 || Ctor->getMinRequiredArguments() > 1)
    return;

  bool takesInitializerList = isStdInitializerList(
      Ctor->getParamDecl(0)->getType().getNonReferenceType());
  if (Ctor->isExplicit() &&
      (Ctor->isCopyOrMoveConstructor() || takesInitializerList)) {
    auto isKWExplicit = [](const Token &Tok) {
      return Tok.is(tok::raw_identifier) &&
             Tok.getRawIdentifier() == "explicit";
    };
    SourceRange ExplicitTokenRange =
        FindToken(*Result.SourceManager, Result.Context->getLangOpts(),
                  Ctor->getOuterLocStart(), Ctor->getLocEnd(), isKWExplicit);
    StringRef ConstructorDescription;
    if (Ctor->isMoveConstructor())
      ConstructorDescription = "move";
    else if (Ctor->isCopyConstructor())
      ConstructorDescription = "copy";
    else
      ConstructorDescription = "initializer-list";

    DiagnosticBuilder Diag =
        diag(Ctor->getLocation(),
             "%0 constructor should not be declared explicit")
        << ConstructorDescription;
    if (ExplicitTokenRange.isValid()) {
      Diag << FixItHint::CreateRemoval(
          CharSourceRange::getCharRange(ExplicitTokenRange));
    }
    return;
  }

  if (Ctor->isExplicit() || Ctor->isCopyOrMoveConstructor() ||
      takesInitializerList)
    return;

  bool SingleArgument =
      Ctor->getNumParams() == 1 && !Ctor->getParamDecl(0)->isParameterPack();
  SourceLocation Loc = Ctor->getLocation();
  diag(Loc,
       "%0 must be marked explicit to avoid unintentional implicit conversions")
      << (SingleArgument
              ? "single-argument constructors"
              : "constructors that are callable with a single argument")
      << FixItHint::CreateInsertion(Loc, "explicit ");
}
コード例 #10
0
ファイル: MPIBugReporter.cpp プロジェクト: harite/MPI-Checker
/**
 * Report there's no matching nonblocking call for request var used by wait.
 *
 * @param callExpr
 * @param requestVar
 * @param node
 */
void MPIBugReporter::reportUnmatchedWait(
    const CallEvent &callEvent, const clang::ento::MemRegion *requestRegion,
    const ExplodedNode *const node) const {
    std::string errorText{"Request '" + util::variableName(requestRegion) +
                          "' has no matching nonblocking call. "};

    auto bugReport =
        llvm::make_unique<BugReport>(*unmatchedWaitBugType_, errorText, node);
    bugReport->addRange(callEvent.getSourceRange());
    SourceRange r = util::sourceRange(requestRegion);
    if (r.isValid()) bugReport->addRange(r);
    bugReporter_.emitReport(std::move(bugReport));
}
コード例 #11
0
ファイル: llvm_codes.cpp プロジェクト: Goettsch/game-editor
/// HighlightRange - Given a SourceRange and a line number, highlight (with ~'s)
/// any characters in LineNo that intersect the SourceRange.
void TextDiagnosticPrinter::HighlightRange(const SourceRange &R,
                                          SourceManager& SourceMgr,
                                           unsigned LineNo,
                                           std::string &CaratLine,
                                           const std::string &SourceLine) {  
  assert(CaratLine.size() == SourceLine.size() &&
         "Expect a correspondence between source and carat line!");
  if (!R.isValid()) return;

  unsigned StartLineNo = SourceMgr.getLogicalLineNumber(R.getBegin());
  if (StartLineNo > LineNo) return;  // No intersection.
  
  unsigned EndLineNo = SourceMgr.getLogicalLineNumber(R.getEnd());
  if (EndLineNo < LineNo) return;  // No intersection.
  
  // Compute the column number of the start.
  unsigned StartColNo = 0;
  if (StartLineNo == LineNo) {
    StartColNo = SourceMgr.getLogicalColumnNumber(R.getBegin());
    if (StartColNo) --StartColNo;  // Zero base the col #.
  }

  // Pick the first non-whitespace column.
  while (StartColNo < SourceLine.size() &&
         (SourceLine[StartColNo] == ' ' || SourceLine[StartColNo] == '\t'))
    ++StartColNo;
  
  // Compute the column number of the end.
  unsigned EndColNo = CaratLine.size();
  if (EndLineNo == LineNo) {
    EndColNo = SourceMgr.getLogicalColumnNumber(R.getEnd());
    if (EndColNo) {
      --EndColNo;  // Zero base the col #.
      
      // Add in the length of the token, so that we cover multi-char tokens.
      EndColNo += Lexer::MeasureTokenLength(R.getEnd(), SourceMgr);
    } else {
      EndColNo = CaratLine.size();
    }
  }
  
  // Pick the last non-whitespace column.
  while (EndColNo-1 &&
         (SourceLine[EndColNo-1] == ' ' || SourceLine[EndColNo-1] == '\t'))
    --EndColNo;
  
  // Fill the range with ~'s.
  assert(StartColNo <= EndColNo && "Invalid range!");
  for (unsigned i = StartColNo; i != EndColNo; ++i)
    CaratLine[i] = '~';
}
コード例 #12
0
// ISSUE: directly copying decls could bring in name conflicts
void RemoveBaseClass::copyBaseClassDecls(void)
{
  if (!getNumExplicitDecls(TheBaseClass))
    return;
  SourceRange BracRange = TheBaseClass->getBraceRange();
  TransAssert(BracRange.isValid() && "Invalid RBraceLoc!");

  SourceLocation StartLoc = BracRange.getBegin();
  SourceLocation EndLoc = BracRange.getEnd().getLocWithOffset(-1);

  std::string DeclsStr = 
    TheRewriter.getRewrittenText(SourceRange(StartLoc, EndLoc));

  TransAssert(!DeclsStr.empty() && "Empty DeclsStr!");
  SourceLocation InsertLoc = TheDerivedClass->getBraceRange().getEnd();
  TheRewriter.InsertTextBefore(InsertLoc, DeclsStr);
}
コード例 #13
0
ファイル: MPIBugReporter.cpp プロジェクト: harite/MPI-Checker
/**
 * Report a missing wait for a nonblocking call.
 *
 * @param requestVar
 * @param node
 */
void MPIBugReporter::reportMissingWait(const RequestVar &requestVar,
                                       const ExplodedNode *const node) const {
    std::string lineNo{lineNumber(requestVar.lastUser_)};
    std::string lastUser =
        requestVar.lastUser_->getCalleeIdentifier()->getName();

    std::string errorText{
        "'" + lastUser + "' in line " + lineNo + ", using request '" +
        requestVar.variableName() +
        "', has no matching wait in the scope of this function. "};

    auto bugReport =
        llvm::make_unique<BugReport>(*missingWaitBugType_, errorText, node);
    bugReport->addRange(requestVar.lastUser_->getSourceRange());
    SourceRange r = util::sourceRange(requestVar.memRegion_);
    if (r.isValid()) bugReport->addRange(r);
    bugReporter_.emitReport(std::move(bugReport));
}
コード例 #14
0
ファイル: MPIBugReporter.cpp プロジェクト: harite/MPI-Checker
/**
 * Report duplicate request use by waits.
 *
 * @param observedCall
 * @param requestVar
 * @param node
 */
void MPIBugReporter::reportDoubleWait(const CallEvent &observedCall,
                                      const RequestVar &requestVar,
                                      const ExplodedNode *const node) const {
    std::string lineNo{lineNumber(requestVar.lastUser_)};
    std::string lastUser =
        requestVar.lastUser_->getCalleeIdentifier()->getName();
    std::string errorText{"Request '" + requestVar.variableName() +
                          "' is already waited upon by '" + lastUser +
                          "' in line " + lineNo + ". "};

    auto bugReport =
        llvm::make_unique<BugReport>(*doubleWaitBugType_, errorText, node);
    bugReport->addRange(observedCall.getSourceRange());
    bugReport->addRange(requestVar.lastUser_->getSourceRange());
    SourceRange r = util::sourceRange(requestVar.memRegion_);
    if (r.isValid()) bugReport->addRange(r);
    bugReporter_.emitReport(std::move(bugReport));
}
コード例 #15
0
void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) {
  IndentScope Indent(*this);
  OS << "TemplateArgument";
  if (R.isValid())
    dumpSourceRange(R);

  switch (A.getKind()) {
  case TemplateArgument::Null:
    OS << " null";
    break;
  case TemplateArgument::Type:
    OS << " type";
    dumpType(A.getAsType());
    break;
  case TemplateArgument::Declaration:
    OS << " decl";
    dumpDeclRef(A.getAsDecl());
    break;
  case TemplateArgument::NullPtr:
    OS << " nullptr";
    break;
  case TemplateArgument::Integral:
    OS << " integral " << A.getAsIntegral();
    break;
  case TemplateArgument::Template:
    OS << " template ";
    A.getAsTemplate().dump(OS);
    break;
  case TemplateArgument::TemplateExpansion:
    OS << " template expansion";
    A.getAsTemplateOrTemplatePattern().dump(OS);
    break;
  case TemplateArgument::Expression:
    OS << " expr";
    dumpStmt(A.getAsExpr());
    break;
  case TemplateArgument::Pack:
    OS << " pack";
    for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end();
         I != E; ++I)
      dumpTemplateArgument(*I);
    break;
  }
}
コード例 #16
0
void StackAddrEscapeChecker::EmitStackError(CheckerContext &C,
                                            const MemRegion *R,
                                            const Expr *RetE) const {
  ExplodedNode *N = C.generateNonFatalErrorNode();
  if (!N)
    return;
  if (!BT_returnstack)
    BT_returnstack = llvm::make_unique<BuiltinBug>(
        this, "Return of address to stack-allocated memory");
  // Generate a report for this bug.
  SmallString<128> buf;
  llvm::raw_svector_ostream os(buf);
  SourceRange range = genName(os, R, C.getASTContext());
  os << " returned to caller";
  auto report = llvm::make_unique<BugReport>(*BT_returnstack, os.str(), N);
  report->addRange(RetE->getSourceRange());
  if (range.isValid())
    report->addRange(range);
  C.emitReport(std::move(report));
}
コード例 #17
0
void StackAddrEscapeChecker::checkReturnedBlockCaptures(
    const BlockDataRegion &B, CheckerContext &C) const {
  for (const MemRegion *Region : getCapturedStackRegions(B, C)) {
    if (isArcManagedBlock(Region, C) || isNotInCurrentFrame(Region, C))
      continue;
    ExplodedNode *N = C.generateNonFatalErrorNode();
    if (!N)
      continue;
    if (!BT_capturedstackret)
      BT_capturedstackret = llvm::make_unique<BuiltinBug>(
          this, "Address of stack-allocated memory is captured");
    SmallString<128> Buf;
    llvm::raw_svector_ostream Out(Buf);
    SourceRange Range = genName(Out, Region, C.getASTContext());
    Out << " is captured by a returned block";
    auto Report =
        llvm::make_unique<BugReport>(*BT_capturedstackret, Out.str(), N);
    if (Range.isValid())
      Report->addRange(Range);
    C.emitReport(std::move(Report));
  }
}
コード例 #18
0
void StackAddrEscapeChecker::EmitStackError(CheckerContext &C, const MemRegion *R,
                                          const Expr *RetE) const {
  ExplodedNode *N = C.generateSink();

  if (!N)
    return;

  if (!BT_returnstack)
   BT_returnstack.reset(
                 new BuiltinBug("Return of address to stack-allocated memory"));

  // Generate a report for this bug.
  SmallString<512> buf;
  llvm::raw_svector_ostream os(buf);
  SourceRange range = GenName(os, R, C.getSourceManager());
  os << " returned to caller";
  BugReport *report = new BugReport(*BT_returnstack, os.str(), N);
  report->addRange(RetE->getSourceRange());
  if (range.isValid())
    report->addRange(range);

  C.EmitReport(report);
}
コード例 #19
0
void StackAddrEscapeChecker::checkAsyncExecutedBlockCaptures(
    const BlockDataRegion &B, CheckerContext &C) const {
  // There is a not-too-uncommon idiom
  // where a block passed to dispatch_async captures a semaphore
  // and then the thread (which called dispatch_async) is blocked on waiting
  // for the completion of the execution of the block 
  // via dispatch_semaphore_wait. To avoid false-positives (for now) 
  // we ignore all the blocks which have captured 
  // a variable of the type "dispatch_semaphore_t".
  if (isSemaphoreCaptured(*B.getDecl()))
    return;
  for (const MemRegion *Region : getCapturedStackRegions(B, C)) {
    // The block passed to dispatch_async may capture another block
    // created on the stack. However, there is no leak in this situaton,
    // no matter if ARC or no ARC is enabled:
    // dispatch_async copies the passed "outer" block (via Block_copy)
    // and if the block has captured another "inner" block,
    // the "inner" block will be copied as well.
    if (isa<BlockDataRegion>(Region))
      continue;
    ExplodedNode *N = C.generateNonFatalErrorNode();
    if (!N)
      continue;
    if (!BT_capturedstackasync)
      BT_capturedstackasync = llvm::make_unique<BuiltinBug>(
          this, "Address of stack-allocated memory is captured");
    SmallString<128> Buf;
    llvm::raw_svector_ostream Out(Buf);
    SourceRange Range = genName(Out, Region, C.getASTContext());
    Out << " is captured by an asynchronously-executed block";
    auto Report =
        llvm::make_unique<BugReport>(*BT_capturedstackasync, Out.str(), N);
    if (Range.isValid())
      Report->addRange(Range);
    C.emitReport(std::move(Report));
  }
}
コード例 #20
0
void ExplicitConstructorCheck::check(const MatchFinder::MatchResult &Result) {
  constexpr char WarningMessage[] =
      "%0 must be marked explicit to avoid unintentional implicit conversions";

  if (const auto *Conversion =
      Result.Nodes.getNodeAs<CXXConversionDecl>("conversion")) {
    if (Conversion->isOutOfLine())
      return;
    SourceLocation Loc = Conversion->getLocation();
    // Ignore all macros until we learn to ignore specific ones (e.g. used in
    // gmock to define matchers).
    if (Loc.isMacroID())
      return;
    diag(Loc, WarningMessage)
        << Conversion << FixItHint::CreateInsertion(Loc, "explicit ");
    return;
  }

  const auto *Ctor = Result.Nodes.getNodeAs<CXXConstructorDecl>("ctor");
  if (Ctor->isOutOfLine() || Ctor->getNumParams() == 0 ||
      Ctor->getMinRequiredArguments() > 1)
    return;

  bool takesInitializerList = isStdInitializerList(
      Ctor->getParamDecl(0)->getType().getNonReferenceType());
  if (Ctor->isExplicit() &&
      (Ctor->isCopyOrMoveConstructor() || takesInitializerList)) {
    auto isKWExplicit = [](const Token &Tok) {
      return Tok.is(tok::raw_identifier) &&
             Tok.getRawIdentifier() == "explicit";
    };
    SourceRange ExplicitTokenRange =
        FindToken(*Result.SourceManager, getLangOpts(),
                  Ctor->getOuterLocStart(), Ctor->getEndLoc(), isKWExplicit);
    StringRef ConstructorDescription;
    if (Ctor->isMoveConstructor())
      ConstructorDescription = "move";
    else if (Ctor->isCopyConstructor())
      ConstructorDescription = "copy";
    else
      ConstructorDescription = "initializer-list";

    auto Diag = diag(Ctor->getLocation(),
                     "%0 constructor should not be declared explicit")
                << ConstructorDescription;
    if (ExplicitTokenRange.isValid()) {
      Diag << FixItHint::CreateRemoval(
          CharSourceRange::getCharRange(ExplicitTokenRange));
    }
    return;
  }

  if (Ctor->isExplicit() || Ctor->isCopyOrMoveConstructor() ||
      takesInitializerList)
    return;

  bool SingleArgument =
      Ctor->getNumParams() == 1 && !Ctor->getParamDecl(0)->isParameterPack();
  SourceLocation Loc = Ctor->getLocation();
  diag(Loc, WarningMessage)
      << (SingleArgument
              ? "single-argument constructors"
              : "constructors that are callable with a single argument")
      << FixItHint::CreateInsertion(Loc, "explicit ");
}
コード例 #21
0
void StackAddrEscapeChecker::checkEndFunction(CheckerContext &Ctx) const {
  if (!ChecksEnabled[CK_StackAddrEscapeChecker])
    return;

  ProgramStateRef State = Ctx.getState();

  // Iterate over all bindings to global variables and see if it contains
  // a memory region in the stack space.
  class CallBack : public StoreManager::BindingsHandler {
  private:
    CheckerContext &Ctx;
    const StackFrameContext *CurSFC;

  public:
    SmallVector<std::pair<const MemRegion *, const MemRegion *>, 10> V;

    CallBack(CheckerContext &CC)
        : Ctx(CC), CurSFC(CC.getLocationContext()->getCurrentStackFrame()) {}

    bool HandleBinding(StoreManager &SMgr, Store S, const MemRegion *Region,
                       SVal Val) override {

      if (!isa<GlobalsSpaceRegion>(Region->getMemorySpace()))
        return true;
      const MemRegion *VR = Val.getAsRegion();
      if (VR && isa<StackSpaceRegion>(VR->getMemorySpace()) &&
          !isArcManagedBlock(VR, Ctx) && !isNotInCurrentFrame(VR, Ctx))
        V.emplace_back(Region, VR);
      return true;
    }
  };

  CallBack Cb(Ctx);
  State->getStateManager().getStoreManager().iterBindings(State->getStore(),
                                                          Cb);

  if (Cb.V.empty())
    return;

  // Generate an error node.
  ExplodedNode *N = Ctx.generateNonFatalErrorNode(State);
  if (!N)
    return;

  if (!BT_stackleak)
    BT_stackleak = llvm::make_unique<BuiltinBug>(
        this, "Stack address stored into global variable",
        "Stack address was saved into a global variable. "
        "This is dangerous because the address will become "
        "invalid after returning from the function");

  for (const auto &P : Cb.V) {
    // Generate a report for this bug.
    SmallString<128> Buf;
    llvm::raw_svector_ostream Out(Buf);
    SourceRange Range = genName(Out, P.second, Ctx.getASTContext());
    Out << " is still referred to by the ";
    if (isa<StaticGlobalSpaceRegion>(P.first->getMemorySpace()))
      Out << "static";
    else
      Out << "global";
    Out << " variable '";
    const VarRegion *VR = cast<VarRegion>(P.first->getBaseRegion());
    Out << *VR->getDecl()
        << "' upon returning to the caller.  This will be a dangling reference";
    auto Report = llvm::make_unique<BugReport>(*BT_stackleak, Out.str(), N);
    if (Range.isValid())
      Report->addRange(Range);

    Ctx.emitReport(std::move(Report));
  }
}
コード例 #22
0
ファイル: CXCursor.cpp プロジェクト: nicolaisi/root
CXCursor cxcursor::MakeCXCursor(const Stmt *S, const Decl *Parent,
                                CXTranslationUnit TU,
                                SourceRange RegionOfInterest) {
    assert(S && TU && "Invalid arguments!");
    CXCursorKind K = CXCursor_NotImplemented;

    switch (S->getStmtClass()) {
    case Stmt::NoStmtClass:
        break;

    case Stmt::CaseStmtClass:
        K = CXCursor_CaseStmt;
        break;

    case Stmt::DefaultStmtClass:
        K = CXCursor_DefaultStmt;
        break;

    case Stmt::IfStmtClass:
        K = CXCursor_IfStmt;
        break;

    case Stmt::SwitchStmtClass:
        K = CXCursor_SwitchStmt;
        break;

    case Stmt::WhileStmtClass:
        K = CXCursor_WhileStmt;
        break;

    case Stmt::DoStmtClass:
        K = CXCursor_DoStmt;
        break;

    case Stmt::ForStmtClass:
        K = CXCursor_ForStmt;
        break;

    case Stmt::GotoStmtClass:
        K = CXCursor_GotoStmt;
        break;

    case Stmt::IndirectGotoStmtClass:
        K = CXCursor_IndirectGotoStmt;
        break;

    case Stmt::ContinueStmtClass:
        K = CXCursor_ContinueStmt;
        break;

    case Stmt::BreakStmtClass:
        K = CXCursor_BreakStmt;
        break;

    case Stmt::ReturnStmtClass:
        K = CXCursor_ReturnStmt;
        break;

    case Stmt::GCCAsmStmtClass:
        K = CXCursor_GCCAsmStmt;
        break;

    case Stmt::MSAsmStmtClass:
        K = CXCursor_MSAsmStmt;
        break;

    case Stmt::ObjCAtTryStmtClass:
        K = CXCursor_ObjCAtTryStmt;
        break;

    case Stmt::ObjCAtCatchStmtClass:
        K = CXCursor_ObjCAtCatchStmt;
        break;

    case Stmt::ObjCAtFinallyStmtClass:
        K = CXCursor_ObjCAtFinallyStmt;
        break;

    case Stmt::ObjCAtThrowStmtClass:
        K = CXCursor_ObjCAtThrowStmt;
        break;

    case Stmt::ObjCAtSynchronizedStmtClass:
        K = CXCursor_ObjCAtSynchronizedStmt;
        break;

    case Stmt::ObjCAutoreleasePoolStmtClass:
        K = CXCursor_ObjCAutoreleasePoolStmt;
        break;

    case Stmt::ObjCForCollectionStmtClass:
        K = CXCursor_ObjCForCollectionStmt;
        break;

    case Stmt::CXXCatchStmtClass:
        K = CXCursor_CXXCatchStmt;
        break;

    case Stmt::CXXTryStmtClass:
        K = CXCursor_CXXTryStmt;
        break;

    case Stmt::CXXForRangeStmtClass:
        K = CXCursor_CXXForRangeStmt;
        break;

    case Stmt::SEHTryStmtClass:
        K = CXCursor_SEHTryStmt;
        break;

    case Stmt::SEHExceptStmtClass:
        K = CXCursor_SEHExceptStmt;
        break;

    case Stmt::SEHFinallyStmtClass:
        K = CXCursor_SEHFinallyStmt;
        break;

    case Stmt::ArrayTypeTraitExprClass:
    case Stmt::AsTypeExprClass:
    case Stmt::AtomicExprClass:
    case Stmt::BinaryConditionalOperatorClass:
    case Stmt::TypeTraitExprClass:
    case Stmt::CXXBindTemporaryExprClass:
    case Stmt::CXXDefaultArgExprClass:
    case Stmt::CXXDefaultInitExprClass:
    case Stmt::CXXStdInitializerListExprClass:
    case Stmt::CXXScalarValueInitExprClass:
    case Stmt::CXXUuidofExprClass:
    case Stmt::ChooseExprClass:
    case Stmt::DesignatedInitExprClass:
    case Stmt::ExprWithCleanupsClass:
    case Stmt::ExpressionTraitExprClass:
    case Stmt::ExtVectorElementExprClass:
    case Stmt::ImplicitCastExprClass:
    case Stmt::ImplicitValueInitExprClass:
    case Stmt::MaterializeTemporaryExprClass:
    case Stmt::ObjCIndirectCopyRestoreExprClass:
    case Stmt::OffsetOfExprClass:
    case Stmt::ParenListExprClass:
    case Stmt::PredefinedExprClass:
    case Stmt::ShuffleVectorExprClass:
    case Stmt::ConvertVectorExprClass:
    case Stmt::UnaryExprOrTypeTraitExprClass:
    case Stmt::VAArgExprClass:
    case Stmt::ObjCArrayLiteralClass:
    case Stmt::ObjCDictionaryLiteralClass:
    case Stmt::ObjCBoxedExprClass:
    case Stmt::ObjCSubscriptRefExprClass:
        K = CXCursor_UnexposedExpr;
        break;

    case Stmt::OpaqueValueExprClass:
        if (Expr *Src = cast<OpaqueValueExpr>(S)->getSourceExpr())
            return MakeCXCursor(Src, Parent, TU, RegionOfInterest);
        K = CXCursor_UnexposedExpr;
        break;

    case Stmt::PseudoObjectExprClass:
        return MakeCXCursor(cast<PseudoObjectExpr>(S)->getSyntacticForm(),
                            Parent, TU, RegionOfInterest);

    case Stmt::CompoundStmtClass:
        K = CXCursor_CompoundStmt;
        break;

    case Stmt::NullStmtClass:
        K = CXCursor_NullStmt;
        break;

    case Stmt::LabelStmtClass:
        K = CXCursor_LabelStmt;
        break;

    case Stmt::AttributedStmtClass:
        K = CXCursor_UnexposedStmt;
        break;

    case Stmt::DeclStmtClass:
        K = CXCursor_DeclStmt;
        break;

    case Stmt::CapturedStmtClass:
        K = CXCursor_UnexposedStmt;
        break;

    case Stmt::IntegerLiteralClass:
        K = CXCursor_IntegerLiteral;
        break;

    case Stmt::FloatingLiteralClass:
        K = CXCursor_FloatingLiteral;
        break;

    case Stmt::ImaginaryLiteralClass:
        K = CXCursor_ImaginaryLiteral;
        break;

    case Stmt::StringLiteralClass:
        K = CXCursor_StringLiteral;
        break;

    case Stmt::CharacterLiteralClass:
        K = CXCursor_CharacterLiteral;
        break;

    case Stmt::ParenExprClass:
        K = CXCursor_ParenExpr;
        break;

    case Stmt::UnaryOperatorClass:
        K = CXCursor_UnaryOperator;
        break;

    case Stmt::CXXNoexceptExprClass:
        K = CXCursor_UnaryExpr;
        break;

    case Stmt::ArraySubscriptExprClass:
        K = CXCursor_ArraySubscriptExpr;
        break;

    case Stmt::BinaryOperatorClass:
        K = CXCursor_BinaryOperator;
        break;

    case Stmt::CompoundAssignOperatorClass:
        K = CXCursor_CompoundAssignOperator;
        break;

    case Stmt::ConditionalOperatorClass:
        K = CXCursor_ConditionalOperator;
        break;

    case Stmt::CStyleCastExprClass:
        K = CXCursor_CStyleCastExpr;
        break;

    case Stmt::CompoundLiteralExprClass:
        K = CXCursor_CompoundLiteralExpr;
        break;

    case Stmt::InitListExprClass:
        K = CXCursor_InitListExpr;
        break;

    case Stmt::AddrLabelExprClass:
        K = CXCursor_AddrLabelExpr;
        break;

    case Stmt::StmtExprClass:
        K = CXCursor_StmtExpr;
        break;

    case Stmt::GenericSelectionExprClass:
        K = CXCursor_GenericSelectionExpr;
        break;

    case Stmt::GNUNullExprClass:
        K = CXCursor_GNUNullExpr;
        break;

    case Stmt::CXXStaticCastExprClass:
        K = CXCursor_CXXStaticCastExpr;
        break;

    case Stmt::CXXDynamicCastExprClass:
        K = CXCursor_CXXDynamicCastExpr;
        break;

    case Stmt::CXXReinterpretCastExprClass:
        K = CXCursor_CXXReinterpretCastExpr;
        break;

    case Stmt::CXXConstCastExprClass:
        K = CXCursor_CXXConstCastExpr;
        break;

    case Stmt::CXXFunctionalCastExprClass:
        K = CXCursor_CXXFunctionalCastExpr;
        break;

    case Stmt::CXXTypeidExprClass:
        K = CXCursor_CXXTypeidExpr;
        break;

    case Stmt::CXXBoolLiteralExprClass:
        K = CXCursor_CXXBoolLiteralExpr;
        break;

    case Stmt::CXXNullPtrLiteralExprClass:
        K = CXCursor_CXXNullPtrLiteralExpr;
        break;

    case Stmt::CXXThisExprClass:
        K = CXCursor_CXXThisExpr;
        break;

    case Stmt::CXXThrowExprClass:
        K = CXCursor_CXXThrowExpr;
        break;

    case Stmt::CXXNewExprClass:
        K = CXCursor_CXXNewExpr;
        break;

    case Stmt::CXXDeleteExprClass:
        K = CXCursor_CXXDeleteExpr;
        break;

    case Stmt::ObjCStringLiteralClass:
        K = CXCursor_ObjCStringLiteral;
        break;

    case Stmt::ObjCEncodeExprClass:
        K = CXCursor_ObjCEncodeExpr;
        break;

    case Stmt::ObjCSelectorExprClass:
        K = CXCursor_ObjCSelectorExpr;
        break;

    case Stmt::ObjCProtocolExprClass:
        K = CXCursor_ObjCProtocolExpr;
        break;

    case Stmt::ObjCBoolLiteralExprClass:
        K = CXCursor_ObjCBoolLiteralExpr;
        break;

    case Stmt::ObjCBridgedCastExprClass:
        K = CXCursor_ObjCBridgedCastExpr;
        break;

    case Stmt::BlockExprClass:
        K = CXCursor_BlockExpr;
        break;

    case Stmt::PackExpansionExprClass:
        K = CXCursor_PackExpansionExpr;
        break;

    case Stmt::SizeOfPackExprClass:
        K = CXCursor_SizeOfPackExpr;
        break;

    case Stmt::DeclRefExprClass:
        if (const ImplicitParamDecl *IPD =
                    dyn_cast_or_null<ImplicitParamDecl>(cast<DeclRefExpr>(S)->getDecl())) {
            if (const ObjCMethodDecl *MD =
                        dyn_cast<ObjCMethodDecl>(IPD->getDeclContext())) {
                if (MD->getSelfDecl() == IPD) {
                    K = CXCursor_ObjCSelfExpr;
                    break;
                }
            }
        }

        K = CXCursor_DeclRefExpr;
        break;

    case Stmt::DependentScopeDeclRefExprClass:
    case Stmt::SubstNonTypeTemplateParmExprClass:
    case Stmt::SubstNonTypeTemplateParmPackExprClass:
    case Stmt::FunctionParmPackExprClass:
    case Stmt::UnresolvedLookupExprClass:
        K = CXCursor_DeclRefExpr;
        break;

    case Stmt::CXXDependentScopeMemberExprClass:
    case Stmt::CXXPseudoDestructorExprClass:
    case Stmt::MemberExprClass:
    case Stmt::MSPropertyRefExprClass:
    case Stmt::ObjCIsaExprClass:
    case Stmt::ObjCIvarRefExprClass:
    case Stmt::ObjCPropertyRefExprClass:
    case Stmt::UnresolvedMemberExprClass:
        K = CXCursor_MemberRefExpr;
        break;

    case Stmt::CallExprClass:
    case Stmt::CXXOperatorCallExprClass:
    case Stmt::CXXMemberCallExprClass:
    case Stmt::CUDAKernelCallExprClass:
    case Stmt::CXXConstructExprClass:
    case Stmt::CXXTemporaryObjectExprClass:
    case Stmt::CXXUnresolvedConstructExprClass:
    case Stmt::UserDefinedLiteralClass:
        K = CXCursor_CallExpr;
        break;

    case Stmt::LambdaExprClass:
        K = CXCursor_LambdaExpr;
        break;

    case Stmt::ObjCMessageExprClass: {
        K = CXCursor_ObjCMessageExpr;
        int SelectorIdIndex = -1;
        // Check if cursor points to a selector id.
        if (RegionOfInterest.isValid() &&
                RegionOfInterest.getBegin() == RegionOfInterest.getEnd()) {
            SmallVector<SourceLocation, 16> SelLocs;
            cast<ObjCMessageExpr>(S)->getSelectorLocs(SelLocs);
            SmallVectorImpl<SourceLocation>::iterator
            I=std::find(SelLocs.begin(), SelLocs.end(),RegionOfInterest.getBegin());
            if (I != SelLocs.end())
                SelectorIdIndex = I - SelLocs.begin();
        }
        CXCursor C = { K, 0, { Parent, S, TU } };
        return getSelectorIdentifierCursor(SelectorIdIndex, C);
    }

    case Stmt::MSDependentExistsStmtClass:
        K = CXCursor_UnexposedStmt;
        break;
    case Stmt::OMPParallelDirectiveClass:
        K = CXCursor_OMPParallelDirective;
        break;
    case Stmt::OMPSimdDirectiveClass:
        K = CXCursor_OMPSimdDirective;
        break;
    }

    CXCursor C = { K, 0, { Parent, S, TU } };
    return C;
}
コード例 #23
0
/// HighlightRange - Given a SourceRange and a line number, highlight (with ~'s)
/// any characters in LineNo that intersect the SourceRange.
void TextDiagnosticPrinter::HighlightRange(const SourceRange &R,
                                           const SourceManager &SM,
                                           unsigned LineNo, FileID FID,
                                           std::string &CaretLine,
                                           const std::string &SourceLine) {
  assert(CaretLine.size() == SourceLine.size() &&
         "Expect a correspondence between source and caret line!");
  if (!R.isValid()) return;

  SourceLocation Begin = SM.getInstantiationLoc(R.getBegin());
  SourceLocation End = SM.getInstantiationLoc(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.getInstantiationRange(R.getEnd()).second;

  unsigned StartLineNo = SM.getInstantiationLineNumber(Begin);
  if (StartLineNo > LineNo || SM.getFileID(Begin) != FID)
    return;  // No intersection.

  unsigned EndLineNo = SM.getInstantiationLineNumber(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.getInstantiationColumnNumber(Begin);
    if (StartColNo) --StartColNo;  // Zero base the col #.
  }

  // Compute the column number of the end.
  unsigned EndColNo = CaretLine.size();
  if (EndLineNo == LineNo) {
    EndColNo = SM.getInstantiationColumnNumber(End);
    if (EndColNo) {
      --EndColNo;  // Zero base the col #.

      // Add in the length of the token, so that we cover multi-char tokens.
      EndColNo += Lexer::MeasureTokenLength(End, SM, *LangOpts);
    } else {
      EndColNo = CaretLine.size();
    }
  }

  assert(StartColNo <= EndColNo && "Invalid range!");
  
  // Pick the first non-whitespace column.
  while (StartColNo < SourceLine.size() &&
         (SourceLine[StartColNo] == ' ' || SourceLine[StartColNo] == '\t'))
    ++StartColNo;
  
  // Pick the last non-whitespace column.
  if (EndColNo > SourceLine.size())
    EndColNo = SourceLine.size();
  while (EndColNo-1 &&
         (SourceLine[EndColNo-1] == ' ' || SourceLine[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??");

  // Fill the range with ~'s.
  for (unsigned i = StartColNo; i < EndColNo; ++i)
    CaretLine[i] = '~';
}
コード例 #24
0
void StackAddrEscapeChecker::checkEndPath(CheckerContext &Ctx) const {
  ProgramStateRef state = Ctx.getState();

  // Iterate over all bindings to global variables and see if it contains
  // a memory region in the stack space.
  class CallBack : public StoreManager::BindingsHandler {
  private:
    CheckerContext &Ctx;
    const StackFrameContext *CurSFC;
  public:
    SmallVector<std::pair<const MemRegion*, const MemRegion*>, 10> V;

    CallBack(CheckerContext &CC) :
      Ctx(CC),
      CurSFC(CC.getLocationContext()->getCurrentStackFrame())
    {}
    
    bool HandleBinding(StoreManager &SMgr, Store store,
                       const MemRegion *region, SVal val) {
      
      if (!isa<GlobalsSpaceRegion>(region->getMemorySpace()))
        return true;
      
      const MemRegion *vR = val.getAsRegion();
      if (!vR)
        return true;
        
      // Under automated retain release, it is okay to assign a block
      // directly to a global variable.
      if (Ctx.getASTContext().getLangOpts().ObjCAutoRefCount &&
          isa<BlockDataRegion>(vR))
        return true;

      if (const StackSpaceRegion *SSR = 
          dyn_cast<StackSpaceRegion>(vR->getMemorySpace())) {
        // If the global variable holds a location in the current stack frame,
        // record the binding to emit a warning.
        if (SSR->getStackFrame() == CurSFC)
          V.push_back(std::make_pair(region, vR));
      }
      
      return true;
    }
  };
    
  CallBack cb(Ctx);
  state->getStateManager().getStoreManager().iterBindings(state->getStore(),cb);

  if (cb.V.empty())
    return;

  // Generate an error node.
  ExplodedNode *N = Ctx.addTransition(state);
  if (!N)
    return;

  if (!BT_stackleak)
    BT_stackleak.reset(
      new BuiltinBug("Stack address stored into global variable",
                     "Stack address was saved into a global variable. "
                     "This is dangerous because the address will become "
                     "invalid after returning from the function"));
  
  for (unsigned i = 0, e = cb.V.size(); i != e; ++i) {
    // Generate a report for this bug.
    SmallString<512> buf;
    llvm::raw_svector_ostream os(buf);
    SourceRange range = GenName(os, cb.V[i].second,
                                Ctx.getSourceManager());
    os << " is still referred to by the global variable '";
    const VarRegion *VR = cast<VarRegion>(cb.V[i].first->getBaseRegion());
    os << *VR->getDecl()
       << "' upon returning to the caller.  This will be a dangling reference";
    BugReport *report = new BugReport(*BT_stackleak, os.str(), N);
    if (range.isValid())
      report->addRange(range);

    Ctx.EmitReport(report);
  }
}
コード例 #25
0
void PreprocessingRecord::SourceRangeSkipped(SourceRange Range,
                                             SourceLocation EndifLoc) {
  assert(Range.isValid());
  SkippedRanges.emplace_back(Range.getBegin(), EndifLoc);
}