Remember to move a type to the correct set when setting the body.
authorRafael Espindola <rafael.espindola@gmail.com>
Fri, 6 Mar 2015 00:50:21 +0000 (00:50 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Fri, 6 Mar 2015 00:50:21 +0000 (00:50 +0000)
We would set the body of a struct type (therefore making it non-opaque)
but were forgetting to move it to the non-opaque set.

Fixes pr22807.

llvm-svn: 231442

llvm/include/llvm/Linker/Linker.h
llvm/lib/Linker/LinkModules.cpp
llvm/test/Linker/Inputs/pr22807-1.ll [new file with mode: 0644]
llvm/test/Linker/Inputs/pr22807-2.ll [new file with mode: 0644]
llvm/test/Linker/pr22807.ll [new file with mode: 0644]

index aac9dcd..5ca815c 100644 (file)
@@ -54,6 +54,7 @@ public:
     NonOpaqueStructTypeSet NonOpaqueStructTypes;
 
     void addNonOpaque(StructType *Ty);
+    void switchToNonOpaque(StructType *Ty);
     void addOpaque(StructType *Ty);
     StructType *findNonOpaque(ArrayRef<Type *> ETypes, bool IsPacked);
     bool hasType(StructType *Ty);
index 7f0fdb3..a81dce2 100644 (file)
@@ -226,6 +226,7 @@ void TypeMapTy::linkDefinedTypeBodies() {
       Elements[I] = get(SrcSTy->getElementType(I));
 
     DstSTy->setBody(Elements, SrcSTy->isPacked());
+    DstStructTypesSet.switchToNonOpaque(DstSTy);
   }
   SrcDefinitionsToResolve.clear();
   DstResolvedOpaqueTypes.clear();
@@ -1678,6 +1679,14 @@ void Linker::IdentifiedStructTypeSet::addNonOpaque(StructType *Ty) {
   NonOpaqueStructTypes.insert(Ty);
 }
 
+void Linker::IdentifiedStructTypeSet::switchToNonOpaque(StructType *Ty) {
+  assert(!Ty->isOpaque());
+  NonOpaqueStructTypes.insert(Ty);
+  bool Removed = OpaqueStructTypes.erase(Ty);
+  (void)Removed;
+  assert(Removed);
+}
+
 void Linker::IdentifiedStructTypeSet::addOpaque(StructType *Ty) {
   assert(Ty->isOpaque());
   OpaqueStructTypes.insert(Ty);
diff --git a/llvm/test/Linker/Inputs/pr22807-1.ll b/llvm/test/Linker/Inputs/pr22807-1.ll
new file mode 100644 (file)
index 0000000..4081a9b
--- /dev/null
@@ -0,0 +1,6 @@
+%struct.A = type { %struct.B* }
+%struct.B = type opaque
+
+define i32 @foo(%struct.A** %A) {
+  ret i32 0
+}
diff --git a/llvm/test/Linker/Inputs/pr22807-2.ll b/llvm/test/Linker/Inputs/pr22807-2.ll
new file mode 100644 (file)
index 0000000..7739b77
--- /dev/null
@@ -0,0 +1,6 @@
+%struct.A = type { %struct.B* }
+%struct.B = type opaque
+
+define i32 @bar(%struct.A* %A) {
+   ret i32 0
+}
diff --git a/llvm/test/Linker/pr22807.ll b/llvm/test/Linker/pr22807.ll
new file mode 100644 (file)
index 0000000..bb4ca2b
--- /dev/null
@@ -0,0 +1,13 @@
+; RUN: llvm-link -S -o - %p/pr22807.ll %p/Inputs/pr22807-1.ll %p/Inputs/pr22807-2.ll | FileCheck %s
+
+; CHECK-NOT: type
+; CHECK: %struct.B = type { %struct.A* }
+; CHECK-NEXT: %struct.A = type { %struct.B* }
+; CHECK-NOT: type
+
+%struct.B = type { %struct.A* }
+%struct.A = type opaque
+
+define i32 @baz(%struct.B* %BB) {
+  ret i32 0
+}