Runtime: Call Set/Dictionary casting hooks in the stdlib with the correct calling convention.

We neglected to pass down the Hashable witness table parameters, leading to Heisenbugs because we would call into invalid witness pointers occasionally when loading the Hashable conformance from corrupted metadata. Fixes rdar://problem/28022201.
This commit is contained in:
Joe Groff
2016-10-12 11:11:40 -07:00
parent b51cf748d2
commit 2b4cba8499
5 changed files with 126 additions and 14 deletions

View File

@@ -2388,14 +2388,18 @@ extern "C"
void _swift_setDownCastIndirect(OpaqueValue *destination,
OpaqueValue *source,
const Metadata *sourceValueType,
const Metadata *targetValueType);
const Metadata *targetValueType,
const void *sourceValueHashable,
const void *targetValueHashable);
SWIFT_CC(swift)
extern "C"
bool _swift_setDownCastConditionalIndirect(OpaqueValue *destination,
OpaqueValue *source,
const Metadata *sourceValueType,
const Metadata *targetValueType);
OpaqueValue *source,
const Metadata *sourceValueType,
const Metadata *targetValueType,
const void *sourceValueHashable,
const void *targetValueHashable);
SWIFT_CC(swift)
extern "C"
@@ -2404,16 +2408,20 @@ void _swift_dictionaryDownCastIndirect(OpaqueValue *destination,
const Metadata *sourceKeyType,
const Metadata *sourceValueType,
const Metadata *targetKeyType,
const Metadata *targetValueType);
const Metadata *targetValueType,
const void *sourceKeyHashable,
const void *targetKeyHashable);
SWIFT_CC(swift)
extern "C"
bool _swift_dictionaryDownCastConditionalIndirect(OpaqueValue *destination,
OpaqueValue *source,
const Metadata *sourceKeyType,
const Metadata *sourceValueType,
const Metadata *targetKeyType,
const Metadata *targetValueType);
OpaqueValue *source,
const Metadata *sourceKeyType,
const Metadata *sourceValueType,
const Metadata *targetKeyType,
const Metadata *targetValueType,
const void *sourceKeyHashable,
const void *targetKeyHashable);
static bool _dynamicCastStructToStruct(OpaqueValue *destination,
OpaqueValue *source,
@@ -2460,25 +2468,29 @@ static bool _dynamicCastStructToStruct(OpaqueValue *destination,
if (flags & DynamicCastFlags::Unconditional) {
_swift_dictionaryDownCastIndirect(source, destination,
sourceArgs[0], sourceArgs[1],
targetArgs[0], targetArgs[1]);
targetArgs[0], targetArgs[1],
sourceArgs[2], targetArgs[2]);
result = true;
} else {
result =
_swift_dictionaryDownCastConditionalIndirect(source, destination,
sourceArgs[0], sourceArgs[1],
targetArgs[0], targetArgs[1]);
targetArgs[0], targetArgs[1],
sourceArgs[2], targetArgs[2]);
}
// Sets.
} else if (descriptor == &_TMnVs3Set) {
if (flags & DynamicCastFlags::Unconditional) {
_swift_setDownCastIndirect(source, destination,
sourceArgs[0], targetArgs[0]);
sourceArgs[0], targetArgs[0],
sourceArgs[1], targetArgs[1]);
result = true;
} else {
result =
_swift_setDownCastConditionalIndirect(source, destination,
sourceArgs[0], targetArgs[0]);
sourceArgs[0], targetArgs[0],
sourceArgs[1], targetArgs[1]);
}
// Other struct types don't support dynamic covariance for now.