summaryrefslogtreecommitdiffstats
path: root/lib/Analysis
diff options
context:
space:
mode:
authordim <dim@FreeBSD.org>2011-07-17 15:40:56 +0000
committerdim <dim@FreeBSD.org>2011-07-17 15:40:56 +0000
commit611ba3ea3300b71eb95dc4e45f20eee5dddd32e1 (patch)
tree2097d084eb235c0b12c0bff3445f4ec7bbaa8a12 /lib/Analysis
parentc49018d9cce52d8c9f34b44865ec3ba8e89a1488 (diff)
downloadFreeBSD-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.cpp6
-rw-r--r--lib/Analysis/CocoaConventions.cpp65
-rw-r--r--lib/Analysis/FormatString.cpp3
-rw-r--r--lib/Analysis/ReachableCode.cpp6
-rw-r--r--lib/Analysis/UninitializedValues.cpp46
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() {}
-
OpenPOWER on IntegriCloud