diff options
author | dim <dim@FreeBSD.org> | 2011-07-17 15:40:56 +0000 |
---|---|---|
committer | dim <dim@FreeBSD.org> | 2011-07-17 15:40:56 +0000 |
commit | 611ba3ea3300b71eb95dc4e45f20eee5dddd32e1 (patch) | |
tree | 2097d084eb235c0b12c0bff3445f4ec7bbaa8a12 /lib/Analysis | |
parent | c49018d9cce52d8c9f34b44865ec3ba8e89a1488 (diff) | |
download | FreeBSD-src-611ba3ea3300b71eb95dc4e45f20eee5dddd32e1.zip FreeBSD-src-611ba3ea3300b71eb95dc4e45f20eee5dddd32e1.tar.gz |
Vendor import of clang trunk r135360:
http://llvm.org/svn/llvm-project/cfe/trunk@135360
Diffstat (limited to 'lib/Analysis')
-rw-r--r-- | lib/Analysis/CFG.cpp | 6 | ||||
-rw-r--r-- | lib/Analysis/CocoaConventions.cpp | 65 | ||||
-rw-r--r-- | lib/Analysis/FormatString.cpp | 3 | ||||
-rw-r--r-- | lib/Analysis/ReachableCode.cpp | 6 | ||||
-rw-r--r-- | lib/Analysis/UninitializedValues.cpp | 46 |
5 files changed, 95 insertions, 31 deletions
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 3e54020..f231c14 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -776,7 +776,7 @@ LocalScope* CFGBuilder::addLocalScopeForVarDecl(VarDecl* VD, QT = RT->getPointeeType(); if (!QT.isConstQualified()) return Scope; - if (!VD->getInit() || !VD->getInit()->Classify(*Context).isRValue()) + if (!VD->extendsLifetimeOfTemporary()) return Scope; } @@ -2763,6 +2763,10 @@ tryAgain: case Stmt::ParenExprClass: E = cast<ParenExpr>(E)->getSubExpr(); goto tryAgain; + + case Stmt::MaterializeTemporaryExprClass: + E = cast<MaterializeTemporaryExpr>(E)->GetTemporaryExpr(); + goto tryAgain; } } diff --git a/lib/Analysis/CocoaConventions.cpp b/lib/Analysis/CocoaConventions.cpp index 946c38c..90f7092 100644 --- a/lib/Analysis/CocoaConventions.cpp +++ b/lib/Analysis/CocoaConventions.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// // -// This file defines +// This file implements cocoa naming convention analysis. // //===----------------------------------------------------------------------===// @@ -36,8 +36,10 @@ using llvm::StringRef; // not release it." // -cocoa::NamingConvention cocoa::deriveNamingConvention(Selector S) { - switch (S.getMethodFamily()) { +cocoa::NamingConvention cocoa::deriveNamingConvention(Selector S, + const ObjCMethodDecl *MD) { + switch (MD && MD->hasAttr<ObjCMethodFamilyAttr>()? MD->getMethodFamily() + : S.getMethodFamily()) { case OMF_None: case OMF_autorelease: case OMF_dealloc: @@ -45,6 +47,7 @@ cocoa::NamingConvention cocoa::deriveNamingConvention(Selector S) { case OMF_retain: case OMF_retainCount: case OMF_self: + case OMF_performSelector: return NoConvention; case OMF_init: @@ -83,12 +86,12 @@ bool cocoa::isRefType(QualType RetTy, llvm::StringRef Prefix, return Name.startswith(Prefix); } -bool cocoa::isCFObjectRef(QualType T) { - return isRefType(T, "CF") || // Core Foundation. - isRefType(T, "CG") || // Core Graphics. - isRefType(T, "DADisk") || // Disk Arbitration API. - isRefType(T, "DADissenter") || - isRefType(T, "DASessionRef"); +bool coreFoundation::isCFObjectRef(QualType T) { + return cocoa::isRefType(T, "CF") || // Core Foundation. + cocoa::isRefType(T, "CG") || // Core Graphics. + cocoa::isRefType(T, "DADisk") || // Disk Arbitration API. + cocoa::isRefType(T, "DADissenter") || + cocoa::isRefType(T, "DASessionRef"); } @@ -123,3 +126,47 @@ bool cocoa::isCocoaObjectRef(QualType Ty) { return false; } + +bool coreFoundation::followsCreateRule(llvm::StringRef functionName) { + llvm::StringRef::iterator it = functionName.begin(); + llvm::StringRef::iterator start = it; + llvm::StringRef::iterator endI = functionName.end(); + + while (true) { + // Scan for the start of 'create' or 'copy'. + for ( ; it != endI ; ++it) { + // Search for the first character. It can either be 'C' or 'c'. + char ch = *it; + if (ch == 'C' || ch == 'c') { + ++it; + break; + } + } + + // Did we hit the end of the string? If so, we didn't find a match. + if (it == endI) + return false; + + // Scan for *lowercase* 'reate' or 'opy', followed by no lowercase + // character. + llvm::StringRef suffix = functionName.substr(it - start); + if (suffix.startswith("reate")) { + it += 5; + } + else if (suffix.startswith("opy")) { + it += 3; + } + else { + // Keep scanning. + continue; + } + + if (it == endI || !islower(*it)) + return true; + + // If we matched a lowercase character, it isn't the end of the + // word. Keep scanning. + } + + return false; +} diff --git a/lib/Analysis/FormatString.cpp b/lib/Analysis/FormatString.cpp index c1b5ea8..5f3cd4c 100644 --- a/lib/Analysis/FormatString.cpp +++ b/lib/Analysis/FormatString.cpp @@ -219,6 +219,7 @@ bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const { argTy = C.getCanonicalType(argTy).getUnqualifiedType(); if (T == argTy) return true; + // Check for "compatible types". if (const BuiltinType *BT = argTy->getAs<BuiltinType>()) switch (BT->getKind()) { default: @@ -227,7 +228,7 @@ bool ArgTypeResult::matchesType(ASTContext &C, QualType argTy) const { case BuiltinType::SChar: return T == C.UnsignedCharTy; case BuiltinType::Char_U: - case BuiltinType::UChar: + case BuiltinType::UChar: return T == C.SignedCharTy; case BuiltinType::Short: return T == C.UnsignedShortTy; diff --git a/lib/Analysis/ReachableCode.cpp b/lib/Analysis/ReachableCode.cpp index 9ac456f..c5b17fc 100644 --- a/lib/Analysis/ReachableCode.cpp +++ b/lib/Analysis/ReachableCode.cpp @@ -16,6 +16,7 @@ #include "llvm/ADT/SmallVector.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/ExprObjC.h" #include "clang/AST/StmtCXX.h" #include "clang/Analysis/Analyses/ReachableCode.h" #include "clang/Analysis/CFG.h" @@ -108,6 +109,11 @@ static SourceLocation GetUnreachableLoc(const CFGBlock &b, SourceRange &R1, case Stmt::CXXTryStmtClass: { return cast<CXXTryStmt>(S)->getHandler(0)->getCatchLoc(); } + case Expr::ObjCBridgedCastExprClass: { + const ObjCBridgedCastExpr *CSC = cast<ObjCBridgedCastExpr>(S); + R1 = CSC->getSubExpr()->getSourceRange(); + return CSC->getLParenLoc(); + } default: ; } R1 = S->getSourceRange(); diff --git a/lib/Analysis/UninitializedValues.cpp b/lib/Analysis/UninitializedValues.cpp index e80e282..1d6959d 100644 --- a/lib/Analysis/UninitializedValues.cpp +++ b/lib/Analysis/UninitializedValues.cpp @@ -288,28 +288,28 @@ class DataflowWorklist { public: DataflowWorklist(const CFG &cfg) : enqueuedBlocks(cfg.getNumBlockIDs()) {} - void enqueue(const CFGBlock *block); void enqueueSuccessors(const CFGBlock *block); const CFGBlock *dequeue(); - }; } -void DataflowWorklist::enqueue(const CFGBlock *block) { - if (!block) - return; - unsigned idx = block->getBlockID(); - if (enqueuedBlocks[idx]) - return; - worklist.push_back(block); - enqueuedBlocks[idx] = true; -} - void DataflowWorklist::enqueueSuccessors(const clang::CFGBlock *block) { + unsigned OldWorklistSize = worklist.size(); for (CFGBlock::const_succ_iterator I = block->succ_begin(), E = block->succ_end(); I != E; ++I) { - enqueue(*I); + const CFGBlock *Successor = *I; + if (!Successor || enqueuedBlocks[Successor->getBlockID()]) + continue; + worklist.push_back(Successor); + enqueuedBlocks[Successor->getBlockID()] = true; } + if (OldWorklistSize == 0 || OldWorklistSize == worklist.size()) + return; + + // Rotate the newly added blocks to the start of the worklist so that it forms + // a proper queue when we pop off the end of the worklist. + std::rotate(worklist.begin(), worklist.begin() + OldWorklistSize, + worklist.end()); } const CFGBlock *DataflowWorklist::dequeue() { @@ -654,15 +654,19 @@ static bool runOnBlock(const CFGBlock *block, const CFG &cfg, return vals.updateValueVectorWithScratch(block); } -void clang::runUninitializedVariablesAnalysis(const DeclContext &dc, - const CFG &cfg, - AnalysisContext &ac, - UninitVariablesHandler &handler) { +void clang::runUninitializedVariablesAnalysis( + const DeclContext &dc, + const CFG &cfg, + AnalysisContext &ac, + UninitVariablesHandler &handler, + UninitVariablesAnalysisStats &stats) { CFGBlockValues vals(cfg); vals.computeSetOfDeclarations(dc); if (vals.hasNoDeclarations()) return; + stats.NumVariablesAnalyzed = vals.getNumEntries(); + // Mark all variables uninitialized at the entry. const CFGBlock &entry = cfg.getEntry(); for (CFGBlock::const_succ_iterator i = entry.succ_begin(), @@ -684,7 +688,8 @@ void clang::runUninitializedVariablesAnalysis(const DeclContext &dc, while (const CFGBlock *block = worklist.dequeue()) { // Did the block change? - bool changed = runOnBlock(block, cfg, ac, vals, wasAnalyzed); + bool changed = runOnBlock(block, cfg, ac, vals, wasAnalyzed); + ++stats.NumBlockVisits; if (changed || !previouslyVisited[block->getBlockID()]) worklist.enqueueSuccessors(block); previouslyVisited[block->getBlockID()] = true; @@ -692,11 +697,12 @@ void clang::runUninitializedVariablesAnalysis(const DeclContext &dc, // Run through the blocks one more time, and report uninitialized variabes. for (CFG::const_iterator BI = cfg.begin(), BE = cfg.end(); BI != BE; ++BI) { - if (wasAnalyzed[(*BI)->getBlockID()]) + if (wasAnalyzed[(*BI)->getBlockID()]) { runOnBlock(*BI, cfg, ac, vals, wasAnalyzed, &handler, /* flagBlockUses */ true); + ++stats.NumBlockVisits; + } } } UninitVariablesHandler::~UninitVariablesHandler() {} - |