[cfe-commits] r122388 - in /cfe/trunk: lib/Checker/Environment.cpp lib/Checker/GRExprEngine.cpp test/Analysis/method-call.cpp
Zhongxing Xu
xuzhongxing at gmail.com
Tue Dec 21 23:20:27 PST 2010
Author: zhongxingxu
Date: Wed Dec 22 01:20:27 2010
New Revision: 122388
URL: http://llvm.org/viewvc/llvm-project?rev=122388&view=rev
Log:
After inlining the CXXConstructExpr, bind the temporary object region to it.
This change is necessary when the variable is a const reference and we need
the l-value of the construct expr. After that, when binding the variable,
recover the lazy compound value when the variable is not a reference.
In Environment, use the value of a no-op cast expression when it has one.
Otherwise, blast-through it.
Modified:
cfe/trunk/lib/Checker/Environment.cpp
cfe/trunk/lib/Checker/GRExprEngine.cpp
cfe/trunk/test/Analysis/method-call.cpp
Modified: cfe/trunk/lib/Checker/Environment.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/Environment.cpp?rev=122388&r1=122387&r2=122388&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/Environment.cpp (original)
+++ cfe/trunk/lib/Checker/Environment.cpp Wed Dec 22 01:20:27 2010
@@ -63,7 +63,12 @@
if (CT->isVoidType())
return UnknownVal();
if (C->getCastKind() == CK_NoOp) {
- E = C->getSubExpr();
+ // If the no-op cast has value, use it. Should we always propagate
+ // values through all levels of no-op casts?
+ if (const SVal* X = ExprBindings.lookup(C))
+ return *X;
+ else
+ E = C->getSubExpr();
continue;
}
break;
Modified: cfe/trunk/lib/Checker/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/GRExprEngine.cpp?rev=122388&r1=122387&r2=122388&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Checker/GRExprEngine.cpp Wed Dec 22 01:20:27 2010
@@ -1475,15 +1475,8 @@
getCXXThisRegion(CCE->getConstructor()->getParent(), calleeCtx);
SVal ThisV = state->getSVal(ThisR);
-
- if (calleeCtx->evalAsLValue()) {
- state = state->BindExpr(CCE, ThisV);
- } else {
- loc::MemRegionVal *V = cast<loc::MemRegionVal>(&ThisV);
- SVal ObjVal = state->getSVal(V->getRegion());
- assert(isa<nonloc::LazyCompoundVal>(ObjVal));
- state = state->BindExpr(CCE, ObjVal);
- }
+ // Always bind the region to the CXXConstructExpr.
+ state = state->BindExpr(CCE, ThisV);
}
B.generateNode(state);
@@ -2508,7 +2501,12 @@
if (InitEx) {
if (VD->getType()->isReferenceType() && !InitEx->isLValue()) {
- CreateCXXTemporaryObject(InitEx, Pred, Tmp);
+ // If the initializer is C++ record type, it should already has a
+ // temp object.
+ if (!InitEx->getType()->isRecordType())
+ CreateCXXTemporaryObject(InitEx, Pred, Tmp);
+ else
+ Tmp.Add(Pred);
} else
Visit(InitEx, Pred, Tmp);
} else
@@ -2527,6 +2525,14 @@
if (InitEx) {
SVal InitVal = state->getSVal(InitEx);
+ // We bound the temp obj region to the CXXConstructExpr. Now recover
+ // the lazy compound value when the variable is not a reference.
+ if (AMgr.getLangOptions().CPlusPlus && VD->getType()->isRecordType() &&
+ !VD->getType()->isReferenceType() && isa<loc::MemRegionVal>(InitVal)){
+ InitVal = state->getSVal(cast<loc::MemRegionVal>(InitVal).getRegion());
+ assert(isa<nonloc::LazyCompoundVal>(InitVal));
+ }
+
// Recover some path-sensitivity if a scalar value evaluated to
// UnknownVal.
if ((InitVal.isUnknown() ||
Modified: cfe/trunk/test/Analysis/method-call.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/method-call.cpp?rev=122388&r1=122387&r2=122388&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/method-call.cpp (original)
+++ cfe/trunk/test/Analysis/method-call.cpp Wed Dec 22 01:20:27 2010
@@ -1,5 +1,4 @@
// RUN: %clang_cc1 -analyze -analyzer-check-objc-mem -analyzer-inline-call -analyzer-store region -verify %s
-// XFAIL: *
struct A {
int x;
More information about the cfe-commits
mailing list