]> granicus.if.org Git - clang/commitdiff
Revert "[analyzer] Handle zeroing CXXConstructExprs."
authorJordan Rose <jordan_rose@apple.com>
Fri, 21 Jun 2013 16:30:32 +0000 (16:30 +0000)
committerJordan Rose <jordan_rose@apple.com>
Fri, 21 Jun 2013 16:30:32 +0000 (16:30 +0000)
Per review from Anna, this really should have been two commits, and besides
it's causing problems on our internal buildbot. Reverting until these have
been worked out.

This reverts r184511 / 98123284826bb4ce422775563ff1a01580ec5766.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@184561 91177308-0d34-0410-b5e6-96231b3b80d8

lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
test/Analysis/ctor-inlining.mm [moved from test/Analysis/ctor.mm with 84% similarity]
test/Analysis/inlining/path-notes.cpp

index 96ea9f53395392450d9c73a2b14412062c47a4e3..ed90dc589181effc7ed2433908d53d690cf97710 100644 (file)
@@ -176,7 +176,6 @@ void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
       }
 
       // FIXME: This will eventually need to handle new-expressions as well.
-      // Don't forget to update the pre-constructor initialization code below.
     }
 
     // If we couldn't find an existing region to construct into, assume we're
@@ -216,60 +215,22 @@ void ExprEngine::VisitCXXConstructExpr(const CXXConstructExpr *CE,
 
   ExplodedNodeSet DstPreVisit;
   getCheckerManager().runCheckersForPreStmt(DstPreVisit, Pred, CE, *this);
-
-  bool IsArray = isa<ElementRegion>(Target);
-  ExplodedNodeSet PreInitialized;
-  {
-    StmtNodeBuilder Bldr(DstPreVisit, PreInitialized, *currBldrCtx);
-    if (CE->requiresZeroInitialization()) {
-      // Type of the zero doesn't matter.
-      SVal ZeroVal = svalBuilder.makeZeroVal(getContext().CharTy);
-
-      for (ExplodedNodeSet::iterator I = DstPreVisit.begin(),
-                                     E = DstPreVisit.end();
-           I != E; ++I) {
-        ProgramStateRef State = (*I)->getState();
-        // FIXME: Once we properly handle constructors in new-expressions, we'll
-        // need to invalidate the region before setting a default value, to make
-        // sure there aren't any lingering bindings around. This probably needs
-        // to happen regardless of whether or not the object is zero-initialized
-        // to handle random fields of a placement-initialized object picking up
-        // old bindings. We might only want to do it when we need to, though.
-        // FIXME: This isn't actually correct for arrays -- we need to zero-
-        // initialize the entire array, not just the first element -- but our
-        // handling of arrays everywhere else is weak as well, so this shouldn't
-        // actually make things worse.
-        State = State->bindDefault(loc::MemRegionVal(Target), ZeroVal);
-        Bldr.generateNode(CE, *I, State, /*tag=*/0, ProgramPoint::PreStmtKind);
-      }
-    }
-  }
-
   ExplodedNodeSet DstPreCall;
-  getCheckerManager().runCheckersForPreCall(DstPreCall, PreInitialized,
+  getCheckerManager().runCheckersForPreCall(DstPreCall, DstPreVisit,
                                             *Call, *this);
 
   ExplodedNodeSet DstEvaluated;
   StmtNodeBuilder Bldr(DstPreCall, DstEvaluated, *currBldrCtx);
 
-  if (CE->getConstructor()->isTrivial() && !IsArray) {
-    if (CE->getConstructor()->isCopyOrMoveConstructor()) {
-      for (ExplodedNodeSet::iterator I = DstPreCall.begin(),
-                                     E = DstPreCall.end();
-           I != E; ++I)
-        performTrivialCopy(Bldr, *I, *Call);
-    } else {
-      assert(CE->getConstructor()->isDefaultConstructor());
-
-      // We still have to bind the return value.
-      for (ExplodedNodeSet::iterator I = DstPreCall.begin(),
-                                     E = DstPreCall.end();
-           I != E; ++I) {
-        ProgramStateRef State = (*I)->getState();
-        State = bindReturnValue(*Call, LCtx, State);
-        Bldr.generateNode(CE, *I, State);
-      }
-    }
+  bool IsArray = isa<ElementRegion>(Target);
+  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)
similarity index 84%
rename from test/Analysis/ctor.mm
rename to test/Analysis/ctor-inlining.mm
index 37334fe896e75b9cc6d5760d30398ca253f1cadb..8cdb005968c3141bd7d89e46284b433727ba0290 100644 (file)
@@ -500,78 +500,3 @@ namespace ArrayMembers {
     clang_analyzer_eval(c.values[2].x == 3); // expected-warning{{UNKNOWN}}
   }
 };
-
-namespace ZeroInitialization {
-  struct raw_pair {
-    int p1;
-    int p2;
-  };
-
-  void testVarDecl() {
-    raw_pair p{};
-    clang_analyzer_eval(p.p1 == 0); // expected-warning{{TRUE}}
-    clang_analyzer_eval(p.p2 == 0); // expected-warning{{TRUE}}
-  }
-
-  void testTemporary() {
-    clang_analyzer_eval(raw_pair().p1 == 0); // expected-warning{{TRUE}}
-    clang_analyzer_eval(raw_pair().p2 == 0); // expected-warning{{TRUE}}
-  }
-
-  void testArray() {
-    raw_pair p[2] = {};
-    clang_analyzer_eval(p[0].p1 == 0); // expected-warning{{TRUE}}
-    clang_analyzer_eval(p[0].p2 == 0); // expected-warning{{TRUE}}
-    clang_analyzer_eval(p[1].p1 == 0); // expected-warning{{TRUE}}
-    clang_analyzer_eval(p[1].p2 == 0); // expected-warning{{TRUE}}
-  }
-
-  void testNew() {
-    // FIXME: Pending proper implementation of constructors for 'new'.
-    raw_pair *pp = new raw_pair();
-    clang_analyzer_eval(pp->p1 == 0); // expected-warning{{UNKNOWN}}
-    clang_analyzer_eval(pp->p2 == 0); // expected-warning{{UNKNOWN}}
-  }
-
-  void testArrayNew() {
-    // FIXME: Pending proper implementation of constructors for 'new[]'.
-    raw_pair *p = new raw_pair[2]();
-    clang_analyzer_eval(p[0].p1 == 0); // expected-warning{{UNKNOWN}}
-    clang_analyzer_eval(p[0].p2 == 0); // expected-warning{{UNKNOWN}}
-    clang_analyzer_eval(p[1].p1 == 0); // expected-warning{{UNKNOWN}}
-    clang_analyzer_eval(p[1].p2 == 0); // expected-warning{{UNKNOWN}}
-  }
-
-  struct initializing_pair {
-  public:
-    int x;
-    raw_pair y;
-    initializing_pair() : x(), y() {}
-  };
-  
-  void testFieldInitializers() {
-    initializing_pair p;
-    clang_analyzer_eval(p.x == 0); // expected-warning{{TRUE}}
-    clang_analyzer_eval(p.y.p1 == 0); // expected-warning{{TRUE}}
-    clang_analyzer_eval(p.y.p2 == 0); // expected-warning{{TRUE}}
-  }
-
-  struct subclass : public raw_pair {
-    subclass() = default;
-  };
-
-  void testSubclass() {
-    subclass p;
-    clang_analyzer_eval(p.p1 == 0); // expected-warning{{garbage}}
-  }
-
-  struct initializing_subclass : public raw_pair {
-    initializing_subclass() : raw_pair() {}
-  };
-
-  void testInitializingSubclass() {
-    initializing_subclass p;
-    clang_analyzer_eval(p.p1 == 0); // expected-warning{{TRUE}}
-    clang_analyzer_eval(p.p2 == 0); // expected-warning{{TRUE}}
-  }
-}
index 29637f2c8bbb12d0936f868311958026b8df19a1..810c150e4c313ef0f987f408418cd2d7afad2f05 100644 (file)
@@ -300,6 +300,40 @@ int callGenerateNoteOnDefaultArgument(int o) {
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>31</integer>
+// CHECK-NEXT:            <key>col</key><integer>7</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>31</integer>
+// CHECK-NEXT:            <key>col</key><integer>7</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>31</integer>
+// CHECK-NEXT:            <key>col</key><integer>7</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>31</integer>
+// CHECK-NEXT:            <key>col</key><integer>7</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>32</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>
@@ -853,6 +887,40 @@ int callGenerateNoteOnDefaultArgument(int o) {
 // CHECK-NEXT:         <key>end</key>
 // CHECK-NEXT:          <array>
 // CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>44</integer>
+// CHECK-NEXT:            <key>col</key><integer>5</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>44</integer>
+// CHECK-NEXT:            <key>col</key><integer>13</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:        </dict>
+// CHECK-NEXT:       </array>
+// CHECK-NEXT:     </dict>
+// CHECK-NEXT:     <dict>
+// CHECK-NEXT:      <key>kind</key><string>control</string>
+// CHECK-NEXT:      <key>edges</key>
+// CHECK-NEXT:       <array>
+// CHECK-NEXT:        <dict>
+// CHECK-NEXT:         <key>start</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>44</integer>
+// CHECK-NEXT:            <key>col</key><integer>5</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:           <dict>
+// CHECK-NEXT:            <key>line</key><integer>44</integer>
+// CHECK-NEXT:            <key>col</key><integer>13</integer>
+// CHECK-NEXT:            <key>file</key><integer>0</integer>
+// CHECK-NEXT:           </dict>
+// CHECK-NEXT:          </array>
+// CHECK-NEXT:         <key>end</key>
+// CHECK-NEXT:          <array>
+// CHECK-NEXT:           <dict>
 // CHECK-NEXT:            <key>line</key><integer>46</integer>
 // CHECK-NEXT:            <key>col</key><integer>3</integer>
 // CHECK-NEXT:            <key>file</key><integer>0</integer>