r174069 - Revert "[analyzer] Model trivial copy/move ctors with an aggregate bind."

Jordan Rose jordan_rose at apple.com
Thu Jan 31 10:04:03 PST 2013


Author: jrose
Date: Thu Jan 31 12:04:03 2013
New Revision: 174069

URL: http://llvm.org/viewvc/llvm-project?rev=174069&view=rev
Log:
Revert "[analyzer] Model trivial copy/move ctors with an aggregate bind."

It's causing hangs on our internal analyzer buildbot. Will restore after
investigating.

This reverts r173951 / baa7ca1142990e1ad6d4e9d2c73adb749ff50789.

Modified:
    cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
    cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
    cfe/trunk/test/Analysis/ctor-inlining.mm
    cfe/trunk/test/Analysis/temporaries.cpp

Modified: cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h?rev=174069&r1=174068&r2=174069&view=diff
==============================================================================
--- cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h (original)
+++ cfe/trunk/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h Thu Jan 31 12:04:03 2013
@@ -44,7 +44,6 @@ namespace ento {
 class AnalysisManager;
 class CallEvent;
 class SimpleCall;
-class CXXConstructorCall;
 
 class ExprEngine : public SubEngine {
 public:
@@ -547,10 +546,6 @@ private:
                      ExplodedNode *Pred);
 
   bool replayWithoutInlining(ExplodedNode *P, const LocationContext *CalleeLC);
-
-  /// Models a trivial copy or move constructor call with a simple bind.
-  void performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
-                          const CXXConstructorCall &Call);
 };
 
 /// Traits for storing the call processing policy inside GDM.

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp?rev=174069&r1=174068&r2=174069&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp Thu Jan 31 12:04:03 2013
@@ -49,35 +49,6 @@ void ExprEngine::CreateCXXTemporaryObjec
   Bldr.generateNode(ME, Pred, state->BindExpr(ME, LCtx, V));
 }
 
-void ExprEngine::performTrivialCopy(NodeBuilder &Bldr, ExplodedNode *Pred,
-                                    const CXXConstructorCall &Call) {
-  const CXXConstructExpr *CtorExpr = Call.getOriginExpr();
-  assert(CtorExpr->getConstructor()->isCopyOrMoveConstructor());
-  assert(CtorExpr->getConstructor()->isTrivial());
-
-  SVal ThisVal = Call.getCXXThisVal();
-  const LocationContext *LCtx = Pred->getLocationContext();
-
-  ExplodedNodeSet Dst;
-  Bldr.takeNodes(Pred);
-
-  SVal V = Call.getArgSVal(0);
-
-  // Make sure the value being copied is not unknown.
-  if (const Loc *L = dyn_cast<Loc>(&V))
-    V = Pred->getState()->getSVal(*L);
-
-  evalBind(Dst, CtorExpr, Pred, ThisVal, V, true);
-
-  PostStmt PS(CtorExpr, LCtx);
-  for (ExplodedNodeSet::iterator I = Dst.begin(), E = Dst.end();
-       I != E; ++I) {
-    ProgramStateRef State = (*I)->getState();
-    State = bindReturnValue(Call, LCtx, State);
-    Bldr.generateNode(PS, State, *I);
-  }
-}
-
 void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
                                        ExplodedNode *Pred,
                                        ExplodedNodeSet &destNodes) {
@@ -85,7 +56,6 @@ void ExprEngine::VisitCXXConstructExpr(c
   ProgramStateRef State = Pred->getState();
 
   const MemRegion *Target = 0;
-  bool IsArray = false;
 
   switch (CE->getConstructionKind()) {
   case CXXConstructExpr::CK_Complete: {
@@ -109,7 +79,6 @@ void ExprEngine::VisitCXXConstructExpr(c
                 Target = State->getLValue(AT->getElementType(),
                                           getSValBuilder().makeZeroArrayIndex(),
                                           Base).getAsRegion();
-                IsArray = true;
               } else {
                 Target = State->getLValue(Var, LCtx).getAsRegion();
               }
@@ -179,25 +148,14 @@ void ExprEngine::VisitCXXConstructExpr(c
   getCheckerManager().runCheckersForPreCall(DstPreCall, DstPreVisit,
                                             *Call, *this);
 
-  ExplodedNodeSet DstEvaluated;
-  StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
-
-  if (CE->getConstructor()->isTrivial() &&
-      CE->getConstructor()->isCopyOrMoveConstructor() &&
-      !IsArray) {
-    // FIXME: Handle other kinds of trivial constructors as well.
-    for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
-         I != E; ++I)
-      performTrivialCopy(Bldr, *I, *Call);
-
-  } else {
-    for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
-         I != E; ++I)
-      defaultEvalCall(Bldr, *I, *Call);
-  }
+  ExplodedNodeSet DstInvalidated;
+  StmtNodeBuilder Bldr(DstPreCall, DstInvalidated, *currBldrCtx);
+  for (ExplodedNodeSet::iterator I = DstPreCall.begin(), E = DstPreCall.end();
+       I != E; ++I)
+    defaultEvalCall(Bldr, *I, *Call);
 
   ExplodedNodeSet DstPostCall;
-  getCheckerManager().runCheckersForPostCall(DstPostCall, DstEvaluated,
+  getCheckerManager().runCheckersForPostCall(DstPostCall, DstInvalidated,
                                              *Call, *this);
   getCheckerManager().runCheckersForPostStmt(destNodes, DstPostCall, CE, *this);
 }

Modified: cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp?rev=174069&r1=174068&r2=174069&view=diff
==============================================================================
--- cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp (original)
+++ cfe/trunk/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp Thu Jan 31 12:04:03 2013
@@ -187,23 +187,6 @@ static bool wasDifferentDeclUsedForInlin
   return RuntimeCallee->getCanonicalDecl() != StaticDecl->getCanonicalDecl();
 }
 
-/// Returns true if the CXXConstructExpr \p E was intended to construct a
-/// prvalue for the region in \p V.
-///
-/// Note that we can't just test for rvalue vs. glvalue because
-/// CXXConstructExprs embedded in DeclStmts and initializers are considered
-/// rvalues by the AST, and the analyzer would like to treat them as lvalues.
-static bool isTemporaryPRValue(const CXXConstructExpr *E, SVal V) {
-  if (E->isGLValue())
-    return false;
-
-  const MemRegion *MR = V.getAsRegion();
-  if (!MR)
-    return false;
-
-  return isa<CXXTempObjectRegion>(MR);
-}
-
 /// The call exit is simulated with a sequence of nodes, which occur between 
 /// CallExitBegin and CallExitEnd. The following operations occur between the 
 /// two program points:
@@ -264,9 +247,13 @@ void ExprEngine::processCallExit(Explode
         svalBuilder.getCXXThis(CCE->getConstructor()->getParent(), calleeCtx);
       SVal ThisV = state->getSVal(This);
 
-      // If the constructed object is a temporary prvalue, get its bindings.
-      if (isTemporaryPRValue(CCE, ThisV))
-        ThisV = state->getSVal(cast<Loc>(ThisV));
+      // 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);
     }
@@ -705,13 +692,7 @@ ProgramStateRef ExprEngine::bindReturnVa
     }
     }
   } else if (const CXXConstructorCall *C = dyn_cast<CXXConstructorCall>(&Call)){
-    SVal ThisV = C->getCXXThisVal();
-
-    // If the constructed object is a temporary prvalue, get its bindings.
-    if (isTemporaryPRValue(cast<CXXConstructExpr>(E), ThisV))
-      ThisV = State->getSVal(cast<Loc>(ThisV));
-
-    return State->BindExpr(E, LCtx, ThisV);
+    return State->BindExpr(E, LCtx, C->getCXXThisVal());
   }
 
   // Conjure a symbol if the return value is unknown.

Modified: cfe/trunk/test/Analysis/ctor-inlining.mm
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/ctor-inlining.mm?rev=174069&r1=174068&r2=174069&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/ctor-inlining.mm (original)
+++ cfe/trunk/test/Analysis/ctor-inlining.mm Thu Jan 31 12:04:03 2013
@@ -1,15 +1,8 @@
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -std=c++11 -verify %s
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -fobjc-arc -analyzer-config c++-inlining=constructors -Wno-null-dereference -verify %s
 
 void clang_analyzer_eval(bool);
 void clang_analyzer_checkInlined(bool);
 
-// A simplified version of std::move.
-template <typename T>
-T &&move(T &obj) {
-  return static_cast<T &&>(obj);
-}
-
-
 struct Wrapper {
   __strong id obj;
 };
@@ -124,96 +117,3 @@ namespace ConstructorUsedAsRValue {
     clang_analyzer_eval(result); // expected-warning{{TRUE}}
   }
 }
-
-namespace PODUninitialized {
-  class POD {
-  public:
-    int x, y;
-  };
-
-  class PODWrapper {
-  public:
-    POD p;
-  };
-
-  class NonPOD {
-  public:
-    int x, y;
-
-    NonPOD() {}
-    NonPOD(const NonPOD &Other)
-      : x(Other.x), y(Other.y) // expected-warning {{undefined}}
-    {
-    }
-    NonPOD(NonPOD &&Other)
-    : x(Other.x), y(Other.y) // expected-warning {{undefined}}
-    {
-    }
-  };
-
-  class NonPODWrapper {
-  public:
-    class Inner {
-    public:
-      int x, y;
-
-      Inner() {}
-      Inner(const Inner &Other)
-        : x(Other.x), y(Other.y) // expected-warning {{undefined}}
-      {
-      }
-      Inner(Inner &&Other)
-      : x(Other.x), y(Other.y) // expected-warning {{undefined}}
-      {
-      }
-    };
-
-    Inner p;
-  };
-
-  void testPOD() {
-    POD p;
-    p.x = 1;
-    POD p2 = p; // no-warning
-    clang_analyzer_eval(p2.x == 1); // expected-warning{{TRUE}}
-    POD p3 = move(p); // no-warning
-    clang_analyzer_eval(p3.x == 1); // expected-warning{{TRUE}}
-
-    // Use rvalues as well.
-    clang_analyzer_eval(POD(p3).x == 1); // expected-warning{{TRUE}}
-
-    PODWrapper w;
-    w.p.y = 1;
-    PODWrapper w2 = w; // no-warning
-    clang_analyzer_eval(w2.p.y == 1); // expected-warning{{TRUE}}
-    PODWrapper w3 = move(w); // no-warning
-    clang_analyzer_eval(w3.p.y == 1); // expected-warning{{TRUE}}
-
-    // Use rvalues as well.
-    clang_analyzer_eval(PODWrapper(w3).p.y == 1); // expected-warning{{TRUE}}
-  }
-
-  void testNonPOD() {
-    NonPOD p;
-    p.x = 1;
-    NonPOD p2 = p;
-  }
-
-  void testNonPODMove() {
-    NonPOD p;
-    p.x = 1;
-    NonPOD p2 = move(p);
-  }
-
-  void testNonPODWrapper() {
-    NonPODWrapper w;
-    w.p.y = 1;
-    NonPODWrapper w2 = w;
-  }
-
-  void testNonPODWrapperMove() {
-    NonPODWrapper w;
-    w.p.y = 1;
-    NonPODWrapper w2 = move(w);
-  }
-}

Modified: cfe/trunk/test/Analysis/temporaries.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/temporaries.cpp?rev=174069&r1=174068&r2=174069&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/temporaries.cpp (original)
+++ cfe/trunk/test/Analysis/temporaries.cpp Thu Jan 31 12:04:03 2013
@@ -16,7 +16,7 @@ Trivial getTrivial() {
 }
 
 const Trivial &getTrivialRef() {
-  return Trivial(42); // expected-warning {{Address of stack memory associated with temporary object of type 'const struct Trivial' returned to caller}}
+  return Trivial(42); // expected-warning {{Address of stack memory associated with temporary object of type 'struct Trivial' returned to caller}}
 }
 
 
@@ -25,6 +25,6 @@ NonTrivial getNonTrivial() {
 }
 
 const NonTrivial &getNonTrivialRef() {
-  return NonTrivial(42); // expected-warning {{Address of stack memory associated with temporary object of type 'const struct NonTrivial' returned to caller}}
+  return NonTrivial(42); // expected-warning {{Address of stack memory associated with temporary object of type 'struct NonTrivial' returned to caller}}
 }
 





More information about the cfe-commits mailing list