ValueHandleTest.cpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408
  1. //===- llvm/unittest/Support/ValueHandleTest.cpp - ValueHandle tests --------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm/Support/ValueHandle.h"
  10. #include "llvm/ADT/OwningPtr.h"
  11. #include "llvm/Constants.h"
  12. #include "llvm/Instructions.h"
  13. #include "llvm/LLVMContext.h"
  14. #include "gtest/gtest.h"
  15. #include <memory>
  16. using namespace llvm;
  17. namespace {
  18. class ValueHandle : public testing::Test {
  19. protected:
  20. Constant *ConstantV;
  21. std::auto_ptr<BitCastInst> BitcastV;
  22. ValueHandle() :
  23. ConstantV(ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 0)),
  24. BitcastV(new BitCastInst(ConstantV, Type::getInt32Ty(getGlobalContext()))) {
  25. }
  26. };
  27. class ConcreteCallbackVH : public CallbackVH {
  28. public:
  29. ConcreteCallbackVH(Value *V) : CallbackVH(V) {}
  30. };
  31. TEST_F(ValueHandle, WeakVH_BasicOperation) {
  32. WeakVH WVH(BitcastV.get());
  33. EXPECT_EQ(BitcastV.get(), WVH);
  34. WVH = ConstantV;
  35. EXPECT_EQ(ConstantV, WVH);
  36. // Make sure I can call a method on the underlying Value. It
  37. // doesn't matter which method.
  38. EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), WVH->getType());
  39. EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*WVH).getType());
  40. }
  41. TEST_F(ValueHandle, WeakVH_Comparisons) {
  42. WeakVH BitcastWVH(BitcastV.get());
  43. WeakVH ConstantWVH(ConstantV);
  44. EXPECT_TRUE(BitcastWVH == BitcastWVH);
  45. EXPECT_TRUE(BitcastV.get() == BitcastWVH);
  46. EXPECT_TRUE(BitcastWVH == BitcastV.get());
  47. EXPECT_FALSE(BitcastWVH == ConstantWVH);
  48. EXPECT_TRUE(BitcastWVH != ConstantWVH);
  49. EXPECT_TRUE(BitcastV.get() != ConstantWVH);
  50. EXPECT_TRUE(BitcastWVH != ConstantV);
  51. EXPECT_FALSE(BitcastWVH != BitcastWVH);
  52. // Cast to Value* so comparisons work.
  53. Value *BV = BitcastV.get();
  54. Value *CV = ConstantV;
  55. EXPECT_EQ(BV < CV, BitcastWVH < ConstantWVH);
  56. EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantWVH);
  57. EXPECT_EQ(BV > CV, BitcastWVH > ConstantWVH);
  58. EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantWVH);
  59. EXPECT_EQ(BV < CV, BitcastV.get() < ConstantWVH);
  60. EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantWVH);
  61. EXPECT_EQ(BV > CV, BitcastV.get() > ConstantWVH);
  62. EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantWVH);
  63. EXPECT_EQ(BV < CV, BitcastWVH < ConstantV);
  64. EXPECT_EQ(BV <= CV, BitcastWVH <= ConstantV);
  65. EXPECT_EQ(BV > CV, BitcastWVH > ConstantV);
  66. EXPECT_EQ(BV >= CV, BitcastWVH >= ConstantV);
  67. }
  68. TEST_F(ValueHandle, WeakVH_FollowsRAUW) {
  69. WeakVH WVH(BitcastV.get());
  70. WeakVH WVH_Copy(WVH);
  71. WeakVH WVH_Recreated(BitcastV.get());
  72. BitcastV->replaceAllUsesWith(ConstantV);
  73. EXPECT_EQ(ConstantV, WVH);
  74. EXPECT_EQ(ConstantV, WVH_Copy);
  75. EXPECT_EQ(ConstantV, WVH_Recreated);
  76. }
  77. TEST_F(ValueHandle, WeakVH_NullOnDeletion) {
  78. WeakVH WVH(BitcastV.get());
  79. WeakVH WVH_Copy(WVH);
  80. WeakVH WVH_Recreated(BitcastV.get());
  81. BitcastV.reset();
  82. Value *null_value = NULL;
  83. EXPECT_EQ(null_value, WVH);
  84. EXPECT_EQ(null_value, WVH_Copy);
  85. EXPECT_EQ(null_value, WVH_Recreated);
  86. }
  87. TEST_F(ValueHandle, AssertingVH_BasicOperation) {
  88. AssertingVH<CastInst> AVH(BitcastV.get());
  89. CastInst *implicit_to_exact_type = AVH;
  90. (void)implicit_to_exact_type; // Avoid warning.
  91. AssertingVH<Value> GenericAVH(BitcastV.get());
  92. EXPECT_EQ(BitcastV.get(), GenericAVH);
  93. GenericAVH = ConstantV;
  94. EXPECT_EQ(ConstantV, GenericAVH);
  95. // Make sure I can call a method on the underlying CastInst. It
  96. // doesn't matter which method.
  97. EXPECT_FALSE(AVH->mayWriteToMemory());
  98. EXPECT_FALSE((*AVH).mayWriteToMemory());
  99. }
  100. TEST_F(ValueHandle, AssertingVH_Const) {
  101. const CastInst *ConstBitcast = BitcastV.get();
  102. AssertingVH<const CastInst> AVH(ConstBitcast);
  103. const CastInst *implicit_to_exact_type = AVH;
  104. (void)implicit_to_exact_type; // Avoid warning.
  105. }
  106. TEST_F(ValueHandle, AssertingVH_Comparisons) {
  107. AssertingVH<Value> BitcastAVH(BitcastV.get());
  108. AssertingVH<Value> ConstantAVH(ConstantV);
  109. EXPECT_TRUE(BitcastAVH == BitcastAVH);
  110. EXPECT_TRUE(BitcastV.get() == BitcastAVH);
  111. EXPECT_TRUE(BitcastAVH == BitcastV.get());
  112. EXPECT_FALSE(BitcastAVH == ConstantAVH);
  113. EXPECT_TRUE(BitcastAVH != ConstantAVH);
  114. EXPECT_TRUE(BitcastV.get() != ConstantAVH);
  115. EXPECT_TRUE(BitcastAVH != ConstantV);
  116. EXPECT_FALSE(BitcastAVH != BitcastAVH);
  117. // Cast to Value* so comparisons work.
  118. Value *BV = BitcastV.get();
  119. Value *CV = ConstantV;
  120. EXPECT_EQ(BV < CV, BitcastAVH < ConstantAVH);
  121. EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantAVH);
  122. EXPECT_EQ(BV > CV, BitcastAVH > ConstantAVH);
  123. EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantAVH);
  124. EXPECT_EQ(BV < CV, BitcastV.get() < ConstantAVH);
  125. EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantAVH);
  126. EXPECT_EQ(BV > CV, BitcastV.get() > ConstantAVH);
  127. EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantAVH);
  128. EXPECT_EQ(BV < CV, BitcastAVH < ConstantV);
  129. EXPECT_EQ(BV <= CV, BitcastAVH <= ConstantV);
  130. EXPECT_EQ(BV > CV, BitcastAVH > ConstantV);
  131. EXPECT_EQ(BV >= CV, BitcastAVH >= ConstantV);
  132. }
  133. TEST_F(ValueHandle, AssertingVH_DoesNotFollowRAUW) {
  134. AssertingVH<Value> AVH(BitcastV.get());
  135. BitcastV->replaceAllUsesWith(ConstantV);
  136. EXPECT_EQ(BitcastV.get(), AVH);
  137. }
  138. #ifdef NDEBUG
  139. TEST_F(ValueHandle, AssertingVH_ReducesToPointer) {
  140. EXPECT_EQ(sizeof(CastInst *), sizeof(AssertingVH<CastInst>));
  141. }
  142. #else // !NDEBUG
  143. #ifdef GTEST_HAS_DEATH_TEST
  144. TEST_F(ValueHandle, AssertingVH_Asserts) {
  145. AssertingVH<Value> AVH(BitcastV.get());
  146. EXPECT_DEATH({BitcastV.reset();},
  147. "An asserting value handle still pointed to this value!");
  148. AssertingVH<Value> Copy(AVH);
  149. AVH = NULL;
  150. EXPECT_DEATH({BitcastV.reset();},
  151. "An asserting value handle still pointed to this value!");
  152. Copy = NULL;
  153. BitcastV.reset();
  154. }
  155. #endif // GTEST_HAS_DEATH_TEST
  156. #endif // NDEBUG
  157. TEST_F(ValueHandle, CallbackVH_BasicOperation) {
  158. ConcreteCallbackVH CVH(BitcastV.get());
  159. EXPECT_EQ(BitcastV.get(), CVH);
  160. CVH = ConstantV;
  161. EXPECT_EQ(ConstantV, CVH);
  162. // Make sure I can call a method on the underlying Value. It
  163. // doesn't matter which method.
  164. EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), CVH->getType());
  165. EXPECT_EQ(Type::getInt32Ty(getGlobalContext()), (*CVH).getType());
  166. }
  167. TEST_F(ValueHandle, CallbackVH_Comparisons) {
  168. ConcreteCallbackVH BitcastCVH(BitcastV.get());
  169. ConcreteCallbackVH ConstantCVH(ConstantV);
  170. EXPECT_TRUE(BitcastCVH == BitcastCVH);
  171. EXPECT_TRUE(BitcastV.get() == BitcastCVH);
  172. EXPECT_TRUE(BitcastCVH == BitcastV.get());
  173. EXPECT_FALSE(BitcastCVH == ConstantCVH);
  174. EXPECT_TRUE(BitcastCVH != ConstantCVH);
  175. EXPECT_TRUE(BitcastV.get() != ConstantCVH);
  176. EXPECT_TRUE(BitcastCVH != ConstantV);
  177. EXPECT_FALSE(BitcastCVH != BitcastCVH);
  178. // Cast to Value* so comparisons work.
  179. Value *BV = BitcastV.get();
  180. Value *CV = ConstantV;
  181. EXPECT_EQ(BV < CV, BitcastCVH < ConstantCVH);
  182. EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantCVH);
  183. EXPECT_EQ(BV > CV, BitcastCVH > ConstantCVH);
  184. EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantCVH);
  185. EXPECT_EQ(BV < CV, BitcastV.get() < ConstantCVH);
  186. EXPECT_EQ(BV <= CV, BitcastV.get() <= ConstantCVH);
  187. EXPECT_EQ(BV > CV, BitcastV.get() > ConstantCVH);
  188. EXPECT_EQ(BV >= CV, BitcastV.get() >= ConstantCVH);
  189. EXPECT_EQ(BV < CV, BitcastCVH < ConstantV);
  190. EXPECT_EQ(BV <= CV, BitcastCVH <= ConstantV);
  191. EXPECT_EQ(BV > CV, BitcastCVH > ConstantV);
  192. EXPECT_EQ(BV >= CV, BitcastCVH >= ConstantV);
  193. }
  194. TEST_F(ValueHandle, CallbackVH_CallbackOnDeletion) {
  195. class RecordingVH : public CallbackVH {
  196. public:
  197. int DeletedCalls;
  198. int AURWCalls;
  199. RecordingVH() : DeletedCalls(0), AURWCalls(0) {}
  200. RecordingVH(Value *V) : CallbackVH(V), DeletedCalls(0), AURWCalls(0) {}
  201. private:
  202. virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
  203. virtual void allUsesReplacedWith(Value *) { AURWCalls++; }
  204. };
  205. RecordingVH RVH;
  206. RVH = BitcastV.get();
  207. EXPECT_EQ(0, RVH.DeletedCalls);
  208. EXPECT_EQ(0, RVH.AURWCalls);
  209. BitcastV.reset();
  210. EXPECT_EQ(1, RVH.DeletedCalls);
  211. EXPECT_EQ(0, RVH.AURWCalls);
  212. }
  213. TEST_F(ValueHandle, CallbackVH_CallbackOnRAUW) {
  214. class RecordingVH : public CallbackVH {
  215. public:
  216. int DeletedCalls;
  217. Value *AURWArgument;
  218. RecordingVH() : DeletedCalls(0), AURWArgument(NULL) {}
  219. RecordingVH(Value *V)
  220. : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL) {}
  221. private:
  222. virtual void deleted() { DeletedCalls++; CallbackVH::deleted(); }
  223. virtual void allUsesReplacedWith(Value *new_value) {
  224. EXPECT_EQ(NULL, AURWArgument);
  225. AURWArgument = new_value;
  226. }
  227. };
  228. RecordingVH RVH;
  229. RVH = BitcastV.get();
  230. EXPECT_EQ(0, RVH.DeletedCalls);
  231. EXPECT_EQ(NULL, RVH.AURWArgument);
  232. BitcastV->replaceAllUsesWith(ConstantV);
  233. EXPECT_EQ(0, RVH.DeletedCalls);
  234. EXPECT_EQ(ConstantV, RVH.AURWArgument);
  235. }
  236. TEST_F(ValueHandle, CallbackVH_DeletionCanRAUW) {
  237. class RecoveringVH : public CallbackVH {
  238. public:
  239. int DeletedCalls;
  240. Value *AURWArgument;
  241. LLVMContext *Context;
  242. RecoveringVH() : DeletedCalls(0), AURWArgument(NULL),
  243. Context(&getGlobalContext()) {}
  244. RecoveringVH(Value *V)
  245. : CallbackVH(V), DeletedCalls(0), AURWArgument(NULL),
  246. Context(&getGlobalContext()) {}
  247. private:
  248. virtual void deleted() {
  249. getValPtr()->replaceAllUsesWith(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())));
  250. setValPtr(NULL);
  251. }
  252. virtual void allUsesReplacedWith(Value *new_value) {
  253. ASSERT_TRUE(NULL != getValPtr());
  254. EXPECT_EQ(1U, getValPtr()->getNumUses());
  255. EXPECT_EQ(NULL, AURWArgument);
  256. AURWArgument = new_value;
  257. }
  258. };
  259. // Normally, if a value has uses, deleting it will crash. However, we can use
  260. // a CallbackVH to remove the uses before the check for no uses.
  261. RecoveringVH RVH;
  262. RVH = BitcastV.get();
  263. std::auto_ptr<BinaryOperator> BitcastUser(
  264. BinaryOperator::CreateAdd(RVH,
  265. Constant::getNullValue(Type::getInt32Ty(getGlobalContext()))));
  266. EXPECT_EQ(BitcastV.get(), BitcastUser->getOperand(0));
  267. BitcastV.reset(); // Would crash without the ValueHandler.
  268. EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())), RVH.AURWArgument);
  269. EXPECT_EQ(Constant::getNullValue(Type::getInt32Ty(getGlobalContext())),
  270. BitcastUser->getOperand(0));
  271. }
  272. TEST_F(ValueHandle, DestroyingOtherVHOnSameValueDoesntBreakIteration) {
  273. // When a CallbackVH modifies other ValueHandles in its callbacks,
  274. // that shouldn't interfere with non-modified ValueHandles receiving
  275. // their appropriate callbacks.
  276. //
  277. // We create the active CallbackVH in the middle of a palindromic
  278. // arrangement of other VHs so that the bad behavior would be
  279. // triggered in whichever order callbacks run.
  280. class DestroyingVH : public CallbackVH {
  281. public:
  282. OwningPtr<WeakVH> ToClear[2];
  283. DestroyingVH(Value *V) {
  284. ToClear[0].reset(new WeakVH(V));
  285. setValPtr(V);
  286. ToClear[1].reset(new WeakVH(V));
  287. }
  288. virtual void deleted() {
  289. ToClear[0].reset();
  290. ToClear[1].reset();
  291. CallbackVH::deleted();
  292. }
  293. virtual void allUsesReplacedWith(Value *) {
  294. ToClear[0].reset();
  295. ToClear[1].reset();
  296. }
  297. };
  298. {
  299. WeakVH ShouldBeVisited1(BitcastV.get());
  300. DestroyingVH C(BitcastV.get());
  301. WeakVH ShouldBeVisited2(BitcastV.get());
  302. BitcastV->replaceAllUsesWith(ConstantV);
  303. EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited1));
  304. EXPECT_EQ(ConstantV, static_cast<Value*>(ShouldBeVisited2));
  305. }
  306. {
  307. WeakVH ShouldBeVisited1(BitcastV.get());
  308. DestroyingVH C(BitcastV.get());
  309. WeakVH ShouldBeVisited2(BitcastV.get());
  310. BitcastV.reset();
  311. EXPECT_EQ(NULL, static_cast<Value*>(ShouldBeVisited1));
  312. EXPECT_EQ(NULL, static_cast<Value*>(ShouldBeVisited2));
  313. }
  314. }
  315. TEST_F(ValueHandle, AssertingVHCheckedLast) {
  316. // If a CallbackVH exists to clear out a group of AssertingVHs on
  317. // Value deletion, the CallbackVH should get a chance to do so
  318. // before the AssertingVHs assert.
  319. class ClearingVH : public CallbackVH {
  320. public:
  321. AssertingVH<Value> *ToClear[2];
  322. ClearingVH(Value *V,
  323. AssertingVH<Value> &A0, AssertingVH<Value> &A1)
  324. : CallbackVH(V) {
  325. ToClear[0] = &A0;
  326. ToClear[1] = &A1;
  327. }
  328. virtual void deleted() {
  329. *ToClear[0] = 0;
  330. *ToClear[1] = 0;
  331. CallbackVH::deleted();
  332. }
  333. };
  334. AssertingVH<Value> A1, A2;
  335. A1 = BitcastV.get();
  336. ClearingVH C(BitcastV.get(), A1, A2);
  337. A2 = BitcastV.get();
  338. // C.deleted() should run first, clearing the two AssertingVHs,
  339. // which should prevent them from asserting.
  340. BitcastV.reset();
  341. }
  342. }