ValueHandleTest.cpp 12 KB

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