From 3bd9dcc08f1fc3431b6efdafcc005815141462b7 Mon Sep 17 00:00:00 2001
From: Ted Kremenek <kremenek@apple.com>
Date: Thu, 25 Oct 2007 23:40:35 +0000
Subject: [PATCH] Updated backpatching during object deserialization to support
 "smart" pointers that employ unused bits in a pointer to store extra data.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@43373 91177308-0d34-0410-b5e6-96231b3b80d8
---
 include/llvm/Bitcode/Deserialize.h | 8 ++++++--
 lib/Bitcode/Reader/Deserialize.cpp | 4 +++-
 2 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/include/llvm/Bitcode/Deserialize.h b/include/llvm/Bitcode/Deserialize.h
index 164c70a9af6..6eaba51ecc3 100644
--- a/include/llvm/Bitcode/Deserialize.h
+++ b/include/llvm/Bitcode/Deserialize.h
@@ -20,6 +20,7 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Allocator.h"
+#include "llvm/Support/DataTypes.h"
 #include <vector>
 
 namespace llvm {
@@ -40,8 +41,11 @@ class Deserializer {
   
   struct BPatchNode {
     BPatchNode* const Next;
-    void*& PtrRef;    
-    BPatchNode(BPatchNode* n, void*& pref) : Next(n), PtrRef(pref) {}
+    uintptr_t& PtrRef;
+    BPatchNode(BPatchNode* n, void*& pref) 
+      : Next(n), PtrRef(reinterpret_cast<uintptr_t&>(pref)) {
+        PtrRef = 0;
+      }
   };
   
   struct BPatchEntry {
diff --git a/lib/Bitcode/Reader/Deserialize.cpp b/lib/Bitcode/Reader/Deserialize.cpp
index 3e16027839c..66df46ea23e 100644
--- a/lib/Bitcode/Reader/Deserialize.cpp
+++ b/lib/Bitcode/Reader/Deserialize.cpp
@@ -126,7 +126,9 @@ void Deserializer::BackpatchPointers() {
     assert (Entry.Ptr && "No pointer found for backpatch.");
     
     for (BPatchNode* N = Entry.Head; N != NULL; N = N->Next)
-      N->PtrRef = Entry.Ptr;
+      // Bitwise-OR in the pointer to support "smart" pointers that use
+      // unused bits to store extra data.
+      N->PtrRef |= reinterpret_cast<uintptr_t>(Entry.Ptr);
     
     Entry.Head = NULL;
   }