summaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/RegionStore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/StaticAnalyzer/Core/RegionStore.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/RegionStore.cpp44
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.