aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Function.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/IR/Function.cpp')
-rw-r--r--llvm/lib/IR/Function.cpp15
1 files changed, 13 insertions, 2 deletions
diff --git a/llvm/lib/IR/Function.cpp b/llvm/lib/IR/Function.cpp
index 3298591..87a0770 100644
--- a/llvm/lib/IR/Function.cpp
+++ b/llvm/lib/IR/Function.cpp
@@ -1475,9 +1475,19 @@ static bool matchIntrinsicType(
PointerType *PT = dyn_cast<PointerType>(Ty);
if (!PT || PT->getAddressSpace() != D.Pointer_AddressSpace)
return true;
- if (!PT->isOpaque())
+ if (!PT->isOpaque()) {
+ /* Manually consume a pointer to empty struct descriptor, which is
+ * used for externref. We don't want to enforce that the struct is
+ * anonymous in this case. (This renders externref intrinsics
+ * non-unique, but this will go away with opaque pointers anyway.) */
+ if (Infos.front().Kind == IITDescriptor::Struct &&
+ Infos.front().Struct_NumElements == 0) {
+ Infos = Infos.slice(1);
+ return false;
+ }
return matchIntrinsicType(PT->getNonOpaquePointerElementType(), Infos,
ArgTys, DeferredChecks, IsDeferredCheck);
+ }
// Consume IIT descriptors relating to the pointer element type.
// FIXME: Intrinsic type matching of nested single value types or even
// aggregates doesn't work properly with opaque pointers but hopefully
@@ -1491,7 +1501,8 @@ static bool matchIntrinsicType(
case IITDescriptor::Struct: {
StructType *ST = dyn_cast<StructType>(Ty);
- if (!ST || ST->getNumElements() != D.Struct_NumElements)
+ if (!ST || !ST->isLiteral() || ST->isPacked() ||
+ ST->getNumElements() != D.Struct_NumElements)
return true;
for (unsigned i = 0, e = D.Struct_NumElements; i != e; ++i)