diff options
Diffstat (limited to 'lib/StaticAnalyzer/Core/RegionStore.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/RegionStore.cpp | 44 |
1 files changed, 25 insertions, 19 deletions
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp index 11902f66df91..7f2a481c6b0d 100644 --- a/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/lib/StaticAnalyzer/Core/RegionStore.cpp @@ -18,7 +18,7 @@ #include "clang/AST/Attr.h" #include "clang/AST/CharUnits.h" #include "clang/Analysis/Analyses/LiveVariables.h" -#include "clang/Analysis/AnalysisContext.h" +#include "clang/Analysis/AnalysisDeclContext.h" #include "clang/Basic/TargetInfo.h" #include "clang/StaticAnalyzer/Core/PathSensitive/AnalysisManager.h" #include "clang/StaticAnalyzer/Core/PathSensitive/CallEvent.h" @@ -134,7 +134,9 @@ namespace llvm { }; } // end llvm namespace +#ifndef NDEBUG LLVM_DUMP_METHOD void BindingKey::dump() const { llvm::errs() << *this; } +#endif //===----------------------------------------------------------------------===// // Actual Store type. @@ -1393,17 +1395,17 @@ SVal RegionStoreManager::getBinding(RegionBindingsConstRef B, Loc L, QualType T) return UnknownVal(); } - if (isa<AllocaRegion>(MR) || - isa<SymbolicRegion>(MR) || - isa<CodeTextRegion>(MR)) { + if (!isa<TypedValueRegion>(MR)) { if (T.isNull()) { if (const TypedRegion *TR = dyn_cast<TypedRegion>(MR)) - T = TR->getLocationType(); - else { - const SymbolicRegion *SR = cast<SymbolicRegion>(MR); - T = SR->getSymbol()->getType(); - } + T = TR->getLocationType()->getPointeeType(); + else if (const SymbolicRegion *SR = dyn_cast<SymbolicRegion>(MR)) + T = SR->getSymbol()->getType()->getPointeeType(); + else if (isa<AllocaRegion>(MR)) + T = Ctx.VoidTy; } + assert(!T.isNull() && "Unable to auto-detect binding type!"); + assert(!T->isVoidType() && "Attempting to dereference a void pointer!"); MR = GetElementZeroRegion(cast<SubRegion>(MR), T); } @@ -1859,11 +1861,18 @@ SVal RegionStoreManager::getBindingForVar(RegionBindingsConstRef B, return svalBuilder.getRegionValueSymbolVal(R); // Is 'VD' declared constant? If so, retrieve the constant value. - if (VD->getType().isConstQualified()) - if (const Expr *Init = VD->getInit()) + if (VD->getType().isConstQualified()) { + if (const Expr *Init = VD->getInit()) { if (Optional<SVal> V = svalBuilder.getConstantVal(Init)) return *V; + // If the variable is const qualified and has an initializer but + // we couldn't evaluate initializer to a value, treat the value as + // unknown. + return UnknownVal(); + } + } + // This must come after the check for constants because closure-captured // constant variables may appear in UnknownSpaceRegion. if (isa<UnknownSpaceRegion>(MS)) @@ -2085,15 +2094,12 @@ RegionStoreManager::bindArray(RegionBindingsConstRef B, if (const ConstantArrayType* CAT = dyn_cast<ConstantArrayType>(AT)) Size = CAT->getSize().getZExtValue(); - // Check if the init expr is a string literal. + // Check if the init expr is a literal. If so, bind the rvalue instead. + // FIXME: It's not responsibility of the Store to transform this lvalue + // to rvalue. ExprEngine or maybe even CFG should do this before binding. if (Optional<loc::MemRegionVal> MRV = Init.getAs<loc::MemRegionVal>()) { - const StringRegion *S = cast<StringRegion>(MRV->getRegion()); - - // Treat the string as a lazy compound value. - StoreRef store(B.asStore(), *this); - nonloc::LazyCompoundVal LCV = svalBuilder.makeLazyCompoundVal(store, S) - .castAs<nonloc::LazyCompoundVal>(); - return bindAggregate(B, R, LCV); + SVal V = getBinding(B.asStore(), *MRV, R->getValueType()); + return bindAggregate(B, R, V); } // Handle lazy compound values. |