summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2012-10-01 17:51:35 +0000
committerJordan Rose <jordan_rose@apple.com>2012-10-01 17:51:35 +0000
commit88dd13fdcacf9617437769b25da4be1588496f51 (patch)
treeadd83d98eb116ea0c07aa4b6e3c3493845bfa412
parent3267347ccac4009d14a2be63bde5cc471de244bf (diff)
downloadbcm5719-llvm-88dd13fdcacf9617437769b25da4be1588496f51.tar.gz
bcm5719-llvm-88dd13fdcacf9617437769b25da4be1588496f51.zip
Reapply "[analyzer] Handle inlined constructors for rvalue temporaries correctly."
This is related to but not blocked by <rdar://problem/12137950> ("Return-by-value structs do not have associated regions") This reverts r164875 / 3278d41e17749dbedb204a81ef373499f10251d7. llvm-svn: 164952
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp9
-rw-r--r--clang/test/Analysis/array-struct-region.cpp6
-rw-r--r--clang/test/Analysis/ctor-inlining.mm14
3 files changed, 22 insertions, 7 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index eb5395e93c7..2e460b79e7d 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -160,7 +160,14 @@ void ExprEngine::processCallExit(ExplodedNode *CEBNode) {
svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), calleeCtx);
SVal ThisV = state->getSVal(This);
- // Always bind the region to the CXXConstructExpr.
+ // If the constructed object is a prvalue, get its bindings.
+ // Note that we have to be careful here because constructors embedded
+ // in DeclStmts are not marked as lvalues.
+ if (!CCE->isGLValue())
+ if (const MemRegion *MR = ThisV.getAsRegion())
+ if (isa<CXXTempObjectRegion>(MR))
+ ThisV = state->getSVal(cast<Loc>(ThisV));
+
state = state->BindExpr(CCE, callerCtx, ThisV);
}
}
diff --git a/clang/test/Analysis/array-struct-region.cpp b/clang/test/Analysis/array-struct-region.cpp
index f610fbb2f8d..3581566bdcc 100644
--- a/clang/test/Analysis/array-struct-region.cpp
+++ b/clang/test/Analysis/array-struct-region.cpp
@@ -52,12 +52,6 @@ int getAssignedField(struct S s) {
void testArgument() {
clang_analyzer_eval(getConstrainedField(getS()) == 42); // expected-warning{{TRUE}}
-#if __cplusplus
- // FIXME: Passing the struct by value seems to be confusing C++.
- // Possibly related to <rdar://problem/12137950>.
- // expected-warning@-4{{UNKNOWN}}
-#endif
-
clang_analyzer_eval(getAssignedField(getS()) == 42); // expected-warning{{TRUE}}
}
diff --git a/clang/test/Analysis/ctor-inlining.mm b/clang/test/Analysis/ctor-inlining.mm
index 918de0a4563..ac963e5d9b0 100644
--- a/clang/test/Analysis/ctor-inlining.mm
+++ b/clang/test/Analysis/ctor-inlining.mm
@@ -103,3 +103,17 @@ namespace TemporaryConstructor {
return;
}
}
+
+
+namespace ConstructorUsedAsRValue {
+ using TemporaryConstructor::BoolWrapper;
+
+ bool extractValue(BoolWrapper b) {
+ return b.value;
+ }
+
+ void test() {
+ bool result = extractValue(BoolWrapper());
+ clang_analyzer_eval(result); // expected-warning{{TRUE}}
+ }
+}
OpenPOWER on IntegriCloud