Skip to content

Commit 747b13f

Browse files
committed
[IRGen] Respect optionality of unowned(unsafe) reference properties
rdar://108705703 When generating the type info for fields marked unowned(unsafe) of an optional reference (e.g. AnyObject?), we dropped the fact that it was optional along the way. This caused incorrect tags to be returned when on object of the type was stored in an optional itself and the unowned property contained `nil`. In those cases the outer optional appeared to be `nil` as well, even if it in fact contained a value.
1 parent 38e8ec8 commit 747b13f

File tree

2 files changed

+33
-1
lines changed

2 files changed

+33
-1
lines changed

lib/IRGen/GenExistential.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -798,6 +798,7 @@ namespace {
798798
class Name##ClassExistentialTypeInfo final \
799799
: public ScalarExistentialTypeInfoBase<Name##ClassExistentialTypeInfo, \
800800
LoadableTypeInfo> { \
801+
bool IsOptional; \
801802
public: \
802803
Name##ClassExistentialTypeInfo( \
803804
ArrayRef<const ProtocolDecl *> storedProtocols, \
@@ -807,7 +808,8 @@ namespace {
807808
bool isOptional) \
808809
: ScalarExistentialTypeInfoBase(storedProtocols, ty, size, \
809810
spareBits, align, IsTriviallyDestroyable,\
810-
IsCopyable, IsFixedSize) {} \
811+
IsCopyable, IsFixedSize), \
812+
IsOptional(isOptional) {} \
811813
TypeLayoutEntry \
812814
*buildTypeLayoutEntry(IRGenModule &IGM, \
813815
SILType T, \
@@ -824,6 +826,18 @@ namespace {
824826
else \
825827
return IGM.getUnknownObjectTypeInfo(); \
826828
} \
829+
unsigned getFixedExtraInhabitantCount(IRGenModule &IGM) const override { \
830+
return getValueTypeInfoForExtraInhabitants(IGM) \
831+
.getFixedExtraInhabitantCount(IGM) - IsOptional; \
832+
} \
833+
APInt getFixedExtraInhabitantValue(IRGenModule &IGM, \
834+
unsigned bits, \
835+
unsigned index) const override { \
836+
/* Note that we pass down the original bit-width. */ \
837+
return getValueTypeInfoForExtraInhabitants(IGM) \
838+
.getFixedExtraInhabitantValue(IGM, bits, \
839+
index + IsOptional); \
840+
} \
827841
/* FIXME -- Use REF_STORAGE_HELPER and make */ \
828842
/* getValueTypeInfoForExtraInhabitants call llvm_unreachable() */ \
829843
void emitValueRetain(IRGenFunction &IGF, llvm::Value *value, \

test/Interpreter/rdar108801944.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// RUN: %target-run-simple-swift | %FileCheck %s
2+
// REQUIRES: executable_test
3+
4+
struct Context {
5+
unowned(unsafe) var x: AnyObject? = nil
6+
}
7+
8+
@inline(never)
9+
func test2(x: Context) -> Context? {
10+
return .some(x)
11+
}
12+
13+
// CHECK: works
14+
if (test2(x: Context()) == nil) {
15+
print("bug")
16+
} else {
17+
print("works")
18+
}

0 commit comments

Comments
 (0)