diff options
author | Jordan Rose <jordan_rose@apple.com> | 2012-07-10 22:07:57 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2012-07-10 22:07:57 +0000 |
commit | d1d54aa1314fc4a6f7b001261079456df677c88b (patch) | |
tree | beff7831c2d3ea0e5aecb5fcf88d51e5963205cd /clang/lib/StaticAnalyzer/Core/Calls.cpp | |
parent | fbe6dba15a02fdf30fdbdce40ea15b6452867bce (diff) | |
download | bcm5719-llvm-d1d54aa1314fc4a6f7b001261079456df677c88b.tar.gz bcm5719-llvm-d1d54aa1314fc4a6f7b001261079456df677c88b.zip |
[analyzer] Use CallEvent for building inlined stack frames.
In order to accomplish this, we now build the callee's stack frame
as part of the CallEnter node, rather than the subsequent BlockEdge node.
This should not have any effect on perceived behavior or diagnostics.
This makes it safe to re-enable inlining of member overloaded operators.
llvm-svn: 160022
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/Calls.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/Calls.cpp | 72 |
1 files changed, 52 insertions, 20 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/Calls.cpp b/clang/lib/StaticAnalyzer/Core/Calls.cpp index 8ea1336bb7b..ced1154da75 100644 --- a/clang/lib/StaticAnalyzer/Core/Calls.cpp +++ b/clang/lib/StaticAnalyzer/Core/Calls.cpp @@ -219,20 +219,22 @@ bool CallEvent::mayBeInlined(const Stmt *S) { } -CallEvent::param_iterator AnyFunctionCall::param_begin() const { - const FunctionDecl *D = getDecl(); +CallEvent::param_iterator +AnyFunctionCall::param_begin(bool UseDefinitionParams) const { + const Decl *D = UseDefinitionParams ? getDefinition() : getDecl(); if (!D) return 0; - return D->param_begin(); + return cast<FunctionDecl>(D)->param_begin(); } -CallEvent::param_iterator AnyFunctionCall::param_end() const { - const FunctionDecl *D = getDecl(); +CallEvent::param_iterator +AnyFunctionCall::param_end(bool UseDefinitionParams) const { + const Decl *D = UseDefinitionParams ? getDefinition() : getDecl(); if (!D) return 0; - return D->param_end(); + return cast<FunctionDecl>(D)->param_end(); } QualType AnyFunctionCall::getDeclaredResultType() const { @@ -309,23 +311,31 @@ const FunctionDecl *SimpleCall::getDecl() const { } -void CXXMemberCall::addExtraInvalidatedRegions(RegionList &Regions) const { +SVal CXXMemberCall::getCXXThisVal() const { const Expr *Base = getOriginExpr()->getImplicitObjectArgument(); // FIXME: Will eventually need to cope with member pointers. This is // a limitation in getImplicitObjectArgument(). if (!Base) - return; - - if (const MemRegion *R = getSVal(Base).getAsRegion()) + return UnknownVal(); + + return getSVal(Base); +} + +void CXXMemberCall::addExtraInvalidatedRegions(RegionList &Regions) const { + if (const MemRegion *R = getCXXThisVal().getAsRegion()) Regions.push_back(R); } +SVal CXXMemberOperatorCall::getCXXThisVal() const { + const Expr *Base = getOriginExpr()->getArg(0); + return getSVal(Base); +} + void CXXMemberOperatorCall::addExtraInvalidatedRegions(RegionList &Regions) const { - const Expr *Base = getOriginExpr()->getArg(0); - if (const MemRegion *R = getSVal(Base).getAsRegion()) + if (const MemRegion *R = getCXXThisVal().getAsRegion()) Regions.push_back(R); } @@ -337,14 +347,22 @@ const BlockDataRegion *BlockCall::getBlockRegion() const { return dyn_cast_or_null<BlockDataRegion>(DataReg); } -CallEvent::param_iterator BlockCall::param_begin() const { +CallEvent::param_iterator +BlockCall::param_begin(bool UseDefinitionParams) const { + // Blocks don't have distinct declarations and definitions. + (void)UseDefinitionParams; + const BlockDecl *D = getBlockDecl(); if (!D) return 0; return D->param_begin(); } -CallEvent::param_iterator BlockCall::param_end() const { +CallEvent::param_iterator +BlockCall::param_end(bool UseDefinitionParams) const { + // Blocks don't have distinct declarations and definitions. + (void)UseDefinitionParams; + const BlockDecl *D = getBlockDecl(); if (!D) return 0; @@ -366,32 +384,46 @@ QualType BlockCall::getDeclaredResultType() const { } +SVal CXXConstructorCall::getCXXThisVal() const { + if (Target) + return loc::MemRegionVal(Target); + return UnknownVal(); +} + void CXXConstructorCall::addExtraInvalidatedRegions(RegionList &Regions) const { if (Target) Regions.push_back(Target); } +SVal CXXDestructorCall::getCXXThisVal() const { + if (Target) + return loc::MemRegionVal(Target); + return UnknownVal(); +} + void CXXDestructorCall::addExtraInvalidatedRegions(RegionList &Regions) const { if (Target) Regions.push_back(Target); } -CallEvent::param_iterator ObjCMethodCall::param_begin() const { - const ObjCMethodDecl *D = getDecl(); +CallEvent::param_iterator +ObjCMethodCall::param_begin(bool UseDefinitionParams) const { + const Decl *D = UseDefinitionParams ? getDefinition() : getDecl(); if (!D) return 0; - return D->param_begin(); + return cast<ObjCMethodDecl>(D)->param_begin(); } -CallEvent::param_iterator ObjCMethodCall::param_end() const { - const ObjCMethodDecl *D = getDecl(); +CallEvent::param_iterator +ObjCMethodCall::param_end(bool UseDefinitionParams) const { + const Decl *D = UseDefinitionParams ? getDefinition() : getDecl(); if (!D) return 0; - return D->param_end(); + return cast<ObjCMethodDecl>(D)->param_end(); } void |