diff options
Diffstat (limited to 'clang/lib/StaticAnalyzer')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Checkers/ExprEngine.cpp | 34 | ||||
| -rw-r--r-- | clang/lib/StaticAnalyzer/RegionStore.cpp | 17 | 
2 files changed, 39 insertions, 12 deletions
| diff --git a/clang/lib/StaticAnalyzer/Checkers/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Checkers/ExprEngine.cpp index 1577cbee315..874e7a30642 100644 --- a/clang/lib/StaticAnalyzer/Checkers/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Checkers/ExprEngine.cpp @@ -643,36 +643,52 @@ void ExprEngine::ProcessInitializer(const CFGInitializer Init,    // We don't set EntryNode and currentStmt. And we don't clean up state.    const CXXCtorInitializer *BMI = Init.getInitializer(); -  ExplodedNode *Pred = builder.getPredecessor(); -  const LocationContext *LC = Pred->getLocationContext(); +  ExplodedNode *pred = builder.getPredecessor(); + +  const StackFrameContext *stackFrame = cast<StackFrameContext>(pred->getLocationContext()); +  const CXXConstructorDecl *decl = cast<CXXConstructorDecl>(stackFrame->getDecl()); +  const CXXThisRegion *thisReg = getCXXThisRegion(decl, stackFrame); + +  SVal thisVal = pred->getState()->getSVal(thisReg);    if (BMI->isAnyMemberInitializer()) {      ExplodedNodeSet Dst;      // Evaluate the initializer. -    Visit(BMI->getInit(), Pred, Dst); +    Visit(BMI->getInit(), pred, Dst);      for (ExplodedNodeSet::iterator I = Dst.begin(), E = Dst.end(); I != E; ++I){        ExplodedNode *Pred = *I;        const GRState *state = Pred->getState();        const FieldDecl *FD = BMI->getAnyMember(); -      const RecordDecl *RD = FD->getParent(); -      const CXXThisRegion *ThisR = getCXXThisRegion(cast<CXXRecordDecl>(RD), -                           cast<StackFrameContext>(LC)); -      SVal ThisV = state->getSVal(ThisR); -      SVal FieldLoc = state->getLValue(FD, ThisV); +      SVal FieldLoc = state->getLValue(FD, thisVal);        SVal InitVal = state->getSVal(BMI->getInit());        state = state->bindLoc(FieldLoc, InitVal);        // Use a custom node building process. -      PostInitializer PP(BMI, LC); +      PostInitializer PP(BMI, stackFrame);        // Builder automatically add the generated node to the deferred set,        // which are processed in the builder's dtor.        builder.generateNode(PP, state, Pred);      } +    return;    } + +  assert(BMI->isBaseInitializer()); + +  // Get the base class declaration. +  const CXXConstructExpr *ctorExpr = cast<CXXConstructExpr>(BMI->getInit()); + +  // Create the base object region. +  SVal baseVal =  +    getStoreManager().evalDerivedToBase(thisVal, ctorExpr->getType()); +  const MemRegion *baseReg = baseVal.getAsRegion(); +  assert(baseReg); +  Builder = &builder; +  ExplodedNodeSet dst; +  VisitCXXConstructExpr(ctorExpr, baseReg, pred, dst);  }  void ExprEngine::ProcessImplicitDtor(const CFGImplicitDtor D, diff --git a/clang/lib/StaticAnalyzer/RegionStore.cpp b/clang/lib/StaticAnalyzer/RegionStore.cpp index e47a77e6fc8..58cec303132 100644 --- a/clang/lib/StaticAnalyzer/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/RegionStore.cpp @@ -822,7 +822,8 @@ SVal RegionStoreManager::evalDerivedToBase(SVal derived, QualType baseType) {      return derived;    const MemRegion *baseReg =  -    MRMgr.getCXXBaseObjectRegion(baseDecl, derivedRegVal->getRegion()); +    MRMgr.getCXXBaseObjectRegion(baseDecl, derivedRegVal->getRegion());  +    return loc::MemRegionVal(baseReg);  }  //===----------------------------------------------------------------------===// @@ -1105,6 +1106,17 @@ RegionStoreManager::GetLazyBinding(RegionBindings B, const MemRegion *R) {        return std::make_pair(X.first,                              MRMgr.getFieldRegionWithSuper(FR, X.second));    } +  // C++ base object region is another kind of region that we should blast +  // through to look for lazy compound value. It is like a field region. +  else if (const CXXBaseObjectRegion *baseReg =  +                            dyn_cast<CXXBaseObjectRegion>(R)) { +    const std::pair<Store, const MemRegion *> &X = +      GetLazyBinding(B, baseReg->getSuperRegion()); +     +    if (X.second) +      return std::make_pair(X.first, +                     MRMgr.getCXXBaseObjectRegionWithSuper(baseReg, X.second)); +  }    // The NULL MemRegion indicates an non-existent lazy binding. A NULL Store is    // possible for a valid lazy binding.    return std::make_pair((Store) 0, (const MemRegion *) 0); @@ -1572,7 +1584,6 @@ Store RegionStoreManager::BindStruct(Store store, const TypedRegion* R,  Store RegionStoreManager::KillStruct(Store store, const TypedRegion* R,                                       SVal DefaultVal) { -      BindingKey key = BindingKey::Make(R, BindingKey::Default);    // The BindingKey may be "invalid" if we cannot handle the region binding @@ -1582,7 +1593,7 @@ Store RegionStoreManager::KillStruct(Store store, const TypedRegion* R,    // the case of nested symbolic indices, we need to march up the region    // hierarchy untile we reach a region whose binding we can reason about.    const SubRegion *subReg = R; -   +    while (!key.isValid()) {      if (const SubRegion *tmp = dyn_cast<SubRegion>(subReg->getSuperRegion())) {        subReg = tmp; | 

