From 0504a598a5dc8f3f45e79d4f8ea206a926507859 Mon Sep 17 00:00:00 2001 From: Jordan Rose Date: Mon, 1 Oct 2012 17:51:35 +0000 Subject: [PATCH] Reapply "[analyzer] Handle inlined constructors for rvalue temporaries correctly." This is related to but not blocked by ("Return-by-value structs do not have associated regions") This reverts r164875 / 3278d41e17749dbedb204a81ef373499f10251d7. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@164952 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Core/ExprEngineCallAndReturn.cpp | 9 ++++++++- test/Analysis/array-struct-region.cpp | 6 ------ test/Analysis/ctor-inlining.mm | 14 ++++++++++++++ 3 files changed, 22 insertions(+), 7 deletions(-) diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp index eb5395e93c..2e460b79e7 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp +++ b/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(MR)) + ThisV = state->getSVal(cast(ThisV)); + state = state->BindExpr(CCE, callerCtx, ThisV); } } diff --git a/test/Analysis/array-struct-region.cpp b/test/Analysis/array-struct-region.cpp index f610fbb2f8..3581566bdc 100644 --- a/test/Analysis/array-struct-region.cpp +++ b/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 . - // expected-warning@-4{{UNKNOWN}} -#endif - clang_analyzer_eval(getAssignedField(getS()) == 42); // expected-warning{{TRUE}} } diff --git a/test/Analysis/ctor-inlining.mm b/test/Analysis/ctor-inlining.mm index 918de0a456..ac963e5d9b 100644 --- a/test/Analysis/ctor-inlining.mm +++ b/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}} + } +} -- 2.40.0