aboutsummaryrefslogtreecommitdiff
path: root/lib/StaticAnalyzer/Core/ExprEngine.cpp
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-04-03 01:39:08 +0000
committerJordan Rose <jordan_rose@apple.com>2013-04-03 01:39:08 +0000
commitecee1651c100342366a9417c85c6e50399039930 (patch)
treedf70d7d6ab62bd4765089fb11aac8b0e18067fbb /lib/StaticAnalyzer/Core/ExprEngine.cpp
parent73c56bb0c8e722f4f0c0a044f13064d381f1ec8d (diff)
[analyzer] Better model for copying of array fields in implicit copy ctors.
- Find the correct region to represent the first array element when constructing a CXXConstructorCall. - If the array is trivial, model the copy with a primitive load/store. - Don't warn about the "uninitialized" subscript in the AST -- we don't use the helper variable that Sema provides. <rdar://problem/13091608> git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@178602 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/ExprEngine.cpp')
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngine.cpp33
1 files changed, 30 insertions, 3 deletions
diff --git a/lib/StaticAnalyzer/Core/ExprEngine.cpp b/lib/StaticAnalyzer/Core/ExprEngine.cpp
index 789abb7d86..ffc382fcf0 100644
--- a/lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -432,14 +432,41 @@ void ExprEngine::ProcessInitializer(const CFGInitializer Init,
// but non-objects must be copied in from the initializer.
const Expr *Init = BMI->getInit()->IgnoreImplicit();
if (!isa<CXXConstructExpr>(Init)) {
+ const ValueDecl *Field;
SVal FieldLoc;
- if (BMI->isIndirectMemberInitializer())
+ if (BMI->isIndirectMemberInitializer()) {
+ Field = BMI->getIndirectMember();
FieldLoc = State->getLValue(BMI->getIndirectMember(), thisVal);
- else
+ } else {
+ Field = BMI->getMember();
FieldLoc = State->getLValue(BMI->getMember(), thisVal);
+ }
- SVal InitVal = State->getSVal(BMI->getInit(), stackFrame);
+ SVal InitVal;
+ if (BMI->getNumArrayIndices() > 0) {
+ // Handle arrays of trivial type. We can represent this with a
+ // primitive load/copy from the base array region.
+ const ArraySubscriptExpr *ASE;
+ while ((ASE = dyn_cast<ArraySubscriptExpr>(Init)))
+ Init = ASE->getBase()->IgnoreImplicit();
+
+ SVal LValue = State->getSVal(Init, stackFrame);
+ if (Optional<Loc> LValueLoc = LValue.getAs<Loc>())
+ InitVal = State->getSVal(*LValueLoc);
+
+ // If we fail to get the value for some reason, use a symbolic value.
+ if (InitVal.isUnknownOrUndef()) {
+ SValBuilder &SVB = getSValBuilder();
+ InitVal = SVB.conjureSymbolVal(BMI->getInit(), stackFrame,
+ Field->getType(),
+ currBldrCtx->blockCount());
+ }
+ } else {
+ InitVal = State->getSVal(BMI->getInit(), stackFrame);
+ }
+ assert(Tmp.size() == 1 && "have not generated any new nodes yet");
+ assert(*Tmp.begin() == Pred && "have not generated any new nodes yet");
Tmp.clear();
evalBind(Tmp, Init, Pred, FieldLoc, InitVal, /*isInit=*/true, &PP);
}