[cfe-commits] r164830 - in /cfe/trunk: lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp test/Analysis/array-struct-region.cpp test/Analysis/ctor-inlining.mm

Jordan Rose jordan_rose at apple.com
Fri Sep 28 10:15:25 PDT 2012


Author: jrose
Date: Fri Sep 28 12:15:25 2012
New Revision: 164830

URL: http://llvm.org/viewvc/llvm-project?rev=164830&view=rev
Log:
[analyzer] Handle inlined constructors for rvalue temporaries correctly.

Previously the analyzer treated all inlined constructors like lvalues,
setting the value of the CXXConstructExpr to the newly-constructed
region. However, some CXXConstructExprs behave like rvalues -- in
particular, the implicit copy constructor into a pass-by-value argument.
In this case, we want only the /contents/ of a temporary object to be
passed, so that we can use the same "copy each argument into the
parameter region" algorithm that we use for scalar arguments.

This may change when we start modeling destructors of temporaries,
but for now this is the last part of <rdar://problem/12137950>.

Modified:
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
    cfe/trunk/test/Analysis/array-struct-region.cpp
    cfe/trunk/test/Analysis/ctor-inlining.mm

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp?rev=164830&r1=164829&r2=164830&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Fri Sep 28 12:15:25 2012
@@ -160,7 +160,14 @@
         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);
     }
   }

Modified: cfe/trunk/test/Analysis/array-struct-region.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/array-struct-region.cpp?rev=164830&r1=164829&r2=164830&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/array-struct-region.cpp (original)
+++ cfe/trunk/test/Analysis/array-struct-region.cpp Fri Sep 28 12:15:25 2012
@@ -61,12 +61,6 @@
 
 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 at -4{{UNKNOWN}}
-#endif
-
   clang_analyzer_eval(getAssignedField(getS()) == 42); // expected-warning{{TRUE}}
 }
 

Modified: cfe/trunk/test/Analysis/ctor-inlining.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/ctor-inlining.mm?rev=164830&r1=164829&r2=164830&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/ctor-inlining.mm (original)
+++ cfe/trunk/test/Analysis/ctor-inlining.mm Fri Sep 28 12:15:25 2012
@@ -103,3 +103,17 @@
       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}}
+  }
+}





More information about the cfe-commits mailing list