From 20aa40342bd74895128860c081aa84cd85bfa68d Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Sat, 29 Sep 2012 01:36:47 +0000 Subject: [PATCH] Revert "[analyzer] Create a temp region when a method is called on a struct rvalue." This reverts commit 0006ba445962621ed82ec84400a6b978205a3fbc. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164876 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/StaticAnalyzer/Core/ExprEngine.cpp | 53 +++++++++++--------------- test/Analysis/array-struct-region.cpp | 9 ----- 2 files changed, 22 insertions(+), 40 deletions(-) diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp index 3965f04842..06216f83ea 100644 --- a/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -1470,23 +1470,6 @@ void ExprEngine::VisitLvalArraySubscriptExpr(const ArraySubscriptExpr *A, } } -/// If the value of the given expression is a NonLoc, copy it into a new -/// temporary region, and replace the value of the expression with that. -static ProgramStateRef createTemporaryRegionIfNeeded(ProgramStateRef State, - const LocationContext *LC, - const Expr *E) { - SVal V = State->getSVal(E, LC); - - if (isa(V)) { - MemRegionManager &MRMgr = State->getStateManager().getRegionManager(); - const MemRegion *R = MRMgr.getCXXTempObjectRegion(E, LC); - State = State->bindLoc(loc::MemRegionVal(R), V); - State = State->BindExpr(E, LC, loc::MemRegionVal(R)); - } - - return State; -} - /// VisitMemberExpr - Transfer function for member expressions. void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, ExplodedNodeSet &TopDst) { @@ -1495,7 +1478,6 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, ExplodedNodeSet Dst; Decl *member = M->getMemberDecl(); - // Handle static member variables accessed via member syntax. if (VarDecl *VD = dyn_cast(member)) { assert(M->isGLValue()); Bldr.takeNodes(Pred); @@ -1504,27 +1486,36 @@ void ExprEngine::VisitMemberExpr(const MemberExpr *M, ExplodedNode *Pred, return; } - ProgramStateRef state = Pred->getState(); - const LocationContext *LCtx = Pred->getLocationContext(); - Expr *BaseExpr = M->getBase()->IgnoreParens(); - // Handle C++ method calls. if (const CXXMethodDecl *MD = dyn_cast(member)) { - if (MD->isInstance()) - state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr); - + Bldr.takeNodes(Pred); SVal MDVal = svalBuilder.getFunctionPointer(MD); - state = state->BindExpr(M, LCtx, MDVal); - + ProgramStateRef state = + Pred->getState()->BindExpr(M, Pred->getLocationContext(), MDVal); Bldr.generateNode(M, Pred, state); return; } - // Handle regular struct fields / member variables. - state = createTemporaryRegionIfNeeded(state, LCtx, BaseExpr); - SVal baseExprVal = state->getSVal(BaseExpr, LCtx); - FieldDecl *field = cast(member); + FieldDecl *field = dyn_cast(member); + if (!field) // FIXME: skipping member expressions for non-fields + return; + + Expr *baseExpr = M->getBase()->IgnoreParens(); + ProgramStateRef state = Pred->getState(); + const LocationContext *LCtx = Pred->getLocationContext(); + SVal baseExprVal = state->getSVal(baseExpr, Pred->getLocationContext()); + + // If we're accessing a field of an rvalue, we need to treat it like a + // temporary object. + if (isa(baseExprVal)) { + const MemRegion *R = + svalBuilder.getRegionManager().getCXXTempObjectRegion(baseExpr, LCtx); + SVal L = loc::MemRegionVal(R); + state = state->bindLoc(L, baseExprVal); + baseExprVal = L; + } + SVal L = state->getLValue(field, baseExprVal); if (M->isGLValue()) { ExplodedNodeSet Tmp; diff --git a/test/Analysis/array-struct-region.cpp b/test/Analysis/array-struct-region.cpp index 22fbf2ff33..f610fbb2f8 100644 --- a/test/Analysis/array-struct-region.cpp +++ b/test/Analysis/array-struct-region.cpp @@ -1,7 +1,5 @@ // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c %s // RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -verify -x c++ -analyzer-config c++-inlining=constructors %s -// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c %s -// RUN: %clang_cc1 -analyze -analyzer-checker=core,alpha.core,debug.ExprInspection -DINLINE -verify -x c++ -analyzer-config c++-inlining=constructors %s void clang_analyzer_eval(int); @@ -13,14 +11,7 @@ struct S { #endif }; -#ifdef INLINE -struct S getS() { - struct S s = { 42 }; - return s; -} -#else struct S getS(); -#endif void testAssignment() { -- 2.40.0