diff options
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core')
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/Environment.cpp | 42 | ||||
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/ExprEngine.cpp | 14 | ||||
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/RegionStore.cpp | 26 | ||||
| -rw-r--r-- | clang/lib/StaticAnalyzer/Core/SValBuilder.cpp | 57 | 
4 files changed, 72 insertions, 67 deletions
| diff --git a/clang/lib/StaticAnalyzer/Core/Environment.cpp b/clang/lib/StaticAnalyzer/Core/Environment.cpp index fe352aa8b4c..7b133f6bf64 100644 --- a/clang/lib/StaticAnalyzer/Core/Environment.cpp +++ b/clang/lib/StaticAnalyzer/Core/Environment.cpp @@ -80,43 +80,17 @@ SVal Environment::getSVal(const EnvironmentEntry &Entry,      llvm_unreachable("Should have been handled by ignoreTransparentExprs");    case Stmt::AddrLabelExprClass: -    return svalBuilder.makeLoc(cast<AddrLabelExpr>(S)); - -  case Stmt::CharacterLiteralClass: { -    const CharacterLiteral *C = cast<CharacterLiteral>(S); -    return svalBuilder.makeIntVal(C->getValue(), C->getType()); -  } - +  case Stmt::CharacterLiteralClass:    case Stmt::CXXBoolLiteralExprClass: -    return svalBuilder.makeBoolVal(cast<CXXBoolLiteralExpr>(S)); -    case Stmt::CXXScalarValueInitExprClass: -  case Stmt::ImplicitValueInitExprClass: { -    QualType Ty = cast<Expr>(S)->getType(); -    return svalBuilder.makeZeroVal(Ty); -  } - +  case Stmt::ImplicitValueInitExprClass:    case Stmt::IntegerLiteralClass: -    return svalBuilder.makeIntVal(cast<IntegerLiteral>(S)); -    case Stmt::ObjCBoolLiteralExprClass: -    return svalBuilder.makeBoolVal(cast<ObjCBoolLiteralExpr>(S)); - -  // For special C0xx nullptr case, make a null pointer SVal.    case Stmt::CXXNullPtrLiteralExprClass: -    return svalBuilder.makeNull(); - -  case Stmt::ObjCStringLiteralClass: { -    MemRegionManager &MRMgr = svalBuilder.getRegionManager(); -    const ObjCStringLiteral *SL = cast<ObjCStringLiteral>(S); -    return svalBuilder.makeLoc(MRMgr.getObjCStringRegion(SL)); -  } - -  case Stmt::StringLiteralClass: { -    MemRegionManager &MRMgr = svalBuilder.getRegionManager(); -    const StringLiteral *SL = cast<StringLiteral>(S); -    return svalBuilder.makeLoc(MRMgr.getStringRegion(SL)); -  } +  case Stmt::ObjCStringLiteralClass: +  case Stmt::StringLiteralClass: +    // Known constants; defer to SValBuilder. +    return svalBuilder.getConstantVal(cast<Expr>(S)).getValue();    case Stmt::ReturnStmtClass: {      const ReturnStmt *RS = cast<ReturnStmt>(S); @@ -127,10 +101,8 @@ SVal Environment::getSVal(const EnvironmentEntry &Entry,    // Handle all other Stmt* using a lookup.    default: -    break; +    return lookupExpr(EnvironmentEntry(S, LCtx));    } -   -  return lookupExpr(EnvironmentEntry(S, LCtx));  }  Environment EnvironmentManager::bindExpr(Environment Env, diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp index 5b6e97d3fb4..0d5fb1785b3 100644 --- a/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp +++ b/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp @@ -741,20 +741,14 @@ void ExprEngine::Visit(const Stmt *S, ExplodedNode *Pred,        const CXXDefaultArgExpr *DefaultE = cast<CXXDefaultArgExpr>(S);        const Expr *ArgE = DefaultE->getExpr(); -      // Avoid creating and destroying a lot of APSInts. -      SVal V; -      llvm::APSInt Result; +      Optional<SVal> ConstantVal = svalBuilder.getConstantVal(ArgE); +      if (!ConstantVal) +        ConstantVal = UnknownVal();        for (ExplodedNodeSet::iterator I = PreVisit.begin(), E = PreVisit.end();             I != E; ++I) {          ProgramStateRef State = (*I)->getState(); - -        if (ArgE->EvaluateAsInt(Result, getContext())) -          V = svalBuilder.makeIntVal(Result); -        else -          V = State->getSVal(ArgE, LCtx); - -        State = State->BindExpr(DefaultE, LCtx, V); +        State = State->BindExpr(DefaultE, LCtx, *ConstantVal);          if (DefaultE->isGLValue())            State = createTemporaryRegionIfNeeded(State, LCtx, DefaultE,                                                  DefaultE); diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp index dbfd9d6c990..3053e3610c8 100644 --- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -1755,26 +1755,6 @@ SVal RegionStoreManager::getBindingForObjCIvar(RegionBindingsConstRef B,    return getBindingForLazySymbol(R);  } -static Optional<SVal> getConstValue(SValBuilder &SVB, const VarDecl *VD) { -  ASTContext &Ctx = SVB.getContext(); -  if (!VD->getType().isConstQualified()) -    return None; - -  const Expr *Init = VD->getInit(); -  if (!Init) -    return None; - -  llvm::APSInt Result; -  if (!Init->isGLValue() && Init->EvaluateAsInt(Result, Ctx)) -    return SVB.makeIntVal(Result); - -  if (Init->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull)) -    return SVB.makeNull(); - -  // FIXME: Handle other possible constant expressions. -  return None; -} -  SVal RegionStoreManager::getBindingForVar(RegionBindingsConstRef B,                                            const VarRegion *R) { @@ -1791,8 +1771,10 @@ SVal RegionStoreManager::getBindingForVar(RegionBindingsConstRef B,      return svalBuilder.getRegionValueSymbolVal(R);    // Is 'VD' declared constant?  If so, retrieve the constant value. -  if (Optional<SVal> V = getConstValue(svalBuilder, VD)) -    return *V; +  if (VD->getType().isConstQualified()) +    if (const Expr *Init = VD->getInit()) +      if (Optional<SVal> V = svalBuilder.getConstantVal(Init)) +        return *V;    // This must come after the check for constants because closure-captured    // constant variables may appear in UnknownSpaceRegion. diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp index 5bab986ed05..652809777cf 100644 --- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp +++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp @@ -224,6 +224,63 @@ loc::MemRegionVal SValBuilder::getCXXThis(const CXXRecordDecl *D,    return loc::MemRegionVal(getRegionManager().getCXXThisRegion(PT, SFC));  } +Optional<SVal> SValBuilder::getConstantVal(const Expr *E) { +  E = E->IgnoreParens(); + +  switch (E->getStmtClass()) { +  // Handle expressions that we treat differently from the AST's constant +  // evaluator. +  case Stmt::AddrLabelExprClass: +    return makeLoc(cast<AddrLabelExpr>(E)); + +  case Stmt::CXXScalarValueInitExprClass: +  case Stmt::ImplicitValueInitExprClass: +    return makeZeroVal(E->getType()); + +  case Stmt::ObjCStringLiteralClass: { +    const ObjCStringLiteral *SL = cast<ObjCStringLiteral>(E); +    return makeLoc(getRegionManager().getObjCStringRegion(SL)); +  } + +  case Stmt::StringLiteralClass: { +    const StringLiteral *SL = cast<StringLiteral>(E); +    return makeLoc(getRegionManager().getStringRegion(SL)); +  } + +  // Fast-path some expressions to avoid the overhead of going through the AST's +  // constant evaluator +  case Stmt::CharacterLiteralClass: { +    const CharacterLiteral *C = cast<CharacterLiteral>(E); +    return makeIntVal(C->getValue(), C->getType()); +  } + +  case Stmt::CXXBoolLiteralExprClass: +    return makeBoolVal(cast<CXXBoolLiteralExpr>(E)); + +  case Stmt::IntegerLiteralClass: +    return makeIntVal(cast<IntegerLiteral>(E)); + +  case Stmt::ObjCBoolLiteralExprClass: +    return makeBoolVal(cast<ObjCBoolLiteralExpr>(E)); + +  case Stmt::CXXNullPtrLiteralExprClass: +    return makeNull(); + +  // If we don't have a special case, fall back to the AST's constant evaluator. +  default: { +    ASTContext &Ctx = getContext(); +    llvm::APSInt Result; +    if (E->EvaluateAsInt(Result, Ctx)) +      return makeIntVal(Result); + +    if (E->isNullPointerConstant(Ctx, Expr::NPC_ValueDependentIsNotNull)) +      return makeNull(); + +    return None; +  } +  } +} +  //===----------------------------------------------------------------------===//  SVal SValBuilder::makeSymExprValNN(ProgramStateRef State, | 

