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);
}
}
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}}
}
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}}
+ }
+}