Refine the capture tracking rules for comparisons to be more
authorDan Gohman <gohman@apple.com>
Fri, 20 Nov 2009 00:50:47 +0000 (00:50 +0000)
committerDan Gohman <gohman@apple.com>
Fri, 20 Nov 2009 00:50:47 +0000 (00:50 +0000)
careful about crazy methods of capturing pointers using comparisons.
Comparisons of identified objects with null in the default address
space are not captures. And, comparisons of two pointers within the
same identified object are not captures.

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

lib/Analysis/CaptureTracking.cpp

index 9f27e3dd1808505106fd31f0cfa3f73bbc482788..e86ad96e4a15e821852f997c8ff876aa16766130 100644 (file)
@@ -19,6 +19,7 @@
 #include "llvm/Analysis/CaptureTracking.h"
 #include "llvm/Instructions.h"
 #include "llvm/Value.h"
+#include "llvm/Analysis/AliasAnalysis.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/CallSite.h"
@@ -104,13 +105,25 @@ bool llvm::PointerMayBeCaptured(const Value *V,
           Worklist.push_back(U);
       }
       break;
-    case Instruction::ICmp:
-      // Comparing the pointer against null does not count as a capture.
-      if (ConstantPointerNull *CPN =
-            dyn_cast<ConstantPointerNull>(I->getOperand(1)))
-        if (CPN->getType()->getAddressSpace() == 0)
-          break;
+    case Instruction::ICmp: {
+      // Don't count comparisons of the original value against null as captures.
+      // This allows us to ignore comparisons of malloc results with null,
+      // for example.
+      if (isIdentifiedObject(V))
+        if (ConstantPointerNull *CPN =
+              dyn_cast<ConstantPointerNull>(I->getOperand(1)))
+          if (CPN->getType()->getAddressSpace() == 0)
+            break;
+      // Don't count comparisons of two pointers within the same identified
+      // object as captures.
+      Value *O0 = I->getOperand(0)->getUnderlyingObject();
+      if (isIdentifiedObject(O0) &&
+          O0 == I->getOperand(1)->getUnderlyingObject())
+        break;
+      // Otherwise, be conservative. There are crazy ways to capture pointers
+      // using comparisons.
       return true;
+    }
     default:
       // Something else - be conservative and say it is captured.
       return true;