diff options
-rw-r--r-- | include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h | 28 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/CStringChecker.cpp | 2 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Checkers/MallocChecker.cpp | 2 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/MemRegion.cpp | 14 | ||||
-rw-r--r-- | lib/StaticAnalyzer/Core/SVals.cpp | 3 | ||||
-rw-r--r-- | test/Analysis/static_local.m | 18 |
6 files changed, 48 insertions, 19 deletions
diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h index 8484aefdc3..3c9c33a645 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/MemRegion.h @@ -533,16 +533,28 @@ public: /// FunctionTextRegion - A region that represents code texts of function. class FunctionTextRegion : public CodeTextRegion { - const FunctionDecl *FD; + const NamedDecl *FD; public: - FunctionTextRegion(const FunctionDecl *fd, const MemRegion* sreg) - : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) {} + FunctionTextRegion(const NamedDecl *fd, const MemRegion* sreg) + : CodeTextRegion(sreg, FunctionTextRegionKind), FD(fd) { + assert(isa<ObjCMethodDecl>(fd) || isa<FunctionDecl>(fd)); + } QualType getLocationType() const { - return getContext().getPointerType(FD->getType()); + const ASTContext &Ctx = getContext(); + if (const FunctionDecl *D = dyn_cast<FunctionDecl>(FD)) { + return Ctx.getPointerType(D->getType()); + } + + assert(isa<ObjCMethodDecl>(FD)); + assert(false && "Getting the type of ObjCMethod is not supported yet"); + + // TODO: We might want to return a different type here (ex: id (*ty)(...)) + // depending on how it is used. + return QualType(); } - - const FunctionDecl *getDecl() const { + + const NamedDecl *getDecl() const { return FD; } @@ -550,7 +562,7 @@ public: void Profile(llvm::FoldingSetNodeID& ID) const; - static void ProfileRegion(llvm::FoldingSetNodeID& ID, const FunctionDecl *FD, + static void ProfileRegion(llvm::FoldingSetNodeID& ID, const NamedDecl *FD, const MemRegion*); static bool classof(const MemRegion* R) { @@ -1217,7 +1229,7 @@ public: return getCXXBaseObjectRegion(baseReg->getDecl(), superRegion); } - const FunctionTextRegion *getFunctionTextRegion(const FunctionDecl *FD); + const FunctionTextRegion *getFunctionTextRegion(const NamedDecl *FD); const BlockTextRegion *getBlockTextRegion(const BlockDecl *BD, CanQualType locTy, AnalysisDeclContext *AC); diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index 1e5189d69f..e9ca429521 100644 --- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -842,7 +842,7 @@ bool CStringChecker::SummarizeRegion(raw_ostream &os, ASTContext &Ctx, switch (MR->getKind()) { case MemRegion::FunctionTextRegionKind: { - const FunctionDecl *FD = cast<FunctionTextRegion>(MR)->getDecl(); + const NamedDecl *FD = cast<FunctionTextRegion>(MR)->getDecl(); if (FD) os << "the address of the function '" << *FD << '\''; else diff --git a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp index f57ea12ee0..c036d739dd 100644 --- a/lib/StaticAnalyzer/Checkers/MallocChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/MallocChecker.cpp @@ -739,7 +739,7 @@ bool MallocChecker::SummarizeRegion(raw_ostream &os, const MemRegion *MR) { switch (MR->getKind()) { case MemRegion::FunctionTextRegionKind: { - const FunctionDecl *FD = cast<FunctionTextRegion>(MR)->getDecl(); + const NamedDecl *FD = cast<FunctionTextRegion>(MR)->getDecl(); if (FD) os << "the address of the function '" << *FD << '\''; else diff --git a/lib/StaticAnalyzer/Core/MemRegion.cpp b/lib/StaticAnalyzer/Core/MemRegion.cpp index 8c3c1250e6..48d459452d 100644 --- a/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -352,7 +352,7 @@ void ElementRegion::Profile(llvm::FoldingSetNodeID& ID) const { } void FunctionTextRegion::ProfileRegion(llvm::FoldingSetNodeID& ID, - const FunctionDecl *FD, + const NamedDecl *FD, const MemRegion*) { ID.AddInteger(MemRegion::FunctionTextRegionKind); ID.AddPointer(FD); @@ -748,11 +748,11 @@ const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D, } else { assert(D->isStaticLocal()); - const Decl *D = STC->getDecl(); - if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) + const Decl *STCD = STC->getDecl(); + if (isa<FunctionDecl>(STCD) || isa<ObjCMethodDecl>(STCD)) sReg = getGlobalsRegion(MemRegion::StaticGlobalSpaceRegionKind, - getFunctionTextRegion(FD)); - else if (const BlockDecl *BD = dyn_cast<BlockDecl>(D)) { + getFunctionTextRegion(cast<NamedDecl>(STCD))); + else if (const BlockDecl *BD = dyn_cast<BlockDecl>(STCD)) { const BlockTextRegion *BTR = getBlockTextRegion(BD, C.getCanonicalType(BD->getSignatureAsWritten()->getType()), @@ -761,8 +761,6 @@ const VarRegion* MemRegionManager::getVarRegion(const VarDecl *D, BTR); } else { - // FIXME: For ObjC-methods, we need a new CodeTextRegion. For now - // just use the main global memspace. sReg = getGlobalsRegion(); } } @@ -845,7 +843,7 @@ MemRegionManager::getElementRegion(QualType elementType, NonLoc Idx, } const FunctionTextRegion * -MemRegionManager::getFunctionTextRegion(const FunctionDecl *FD) { +MemRegionManager::getFunctionTextRegion(const NamedDecl *FD) { return getSubRegion<FunctionTextRegion>(FD, getCodeRegion()); } diff --git a/lib/StaticAnalyzer/Core/SVals.cpp b/lib/StaticAnalyzer/Core/SVals.cpp index 8437f50f91..e34ab6a2be 100644 --- a/lib/StaticAnalyzer/Core/SVals.cpp +++ b/lib/StaticAnalyzer/Core/SVals.cpp @@ -51,7 +51,8 @@ const FunctionDecl *SVal::getAsFunctionDecl() const { if (const loc::MemRegionVal* X = dyn_cast<loc::MemRegionVal>(this)) { const MemRegion* R = X->getRegion(); if (const FunctionTextRegion *CTR = R->getAs<FunctionTextRegion>()) - return CTR->getDecl(); + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CTR->getDecl())) + return FD; } return 0; diff --git a/test/Analysis/static_local.m b/test/Analysis/static_local.m new file mode 100644 index 0000000000..709262535f --- /dev/null +++ b/test/Analysis/static_local.m @@ -0,0 +1,18 @@ +// RUN: %clang_cc1 -analyze -analyzer-checker=core -verify -Wno-objc-root-class %s + +// Test reasoning about static locals in ObjCMethods. +int *getValidPtr(); +@interface Radar11275803 +- (int) useStaticInMethod; +@end +@implementation Radar11275803 + +- (int) useStaticInMethod +{ + static int *explInit = 0; + static int implInit; + if (!implInit) + explInit = getValidPtr(); + return *explInit; //no-warning +} +@end
\ No newline at end of file |