diff options
Diffstat (limited to 'llvm/lib/IR/Function.cpp')
-rw-r--r-- | llvm/lib/IR/Function.cpp | 15 |
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) |