Skip to content

Commit 3371080

Browse files
committed
ClangImporter: Built type-checked expressions in union and indirect field accessors
When we remove Sema's UsedConformances list, conformances to _BridgedStoredNSError are checked from SILGen, where its too late to check function bodies of synthesized functions. We could solve this by adding a callback to type check a synthesized function's body, but in fact all synthesized functions are rather trivial so it's better to build their bodies fully type checked. Start by building fully checked expressions for various accessors in ClangImporter.
1 parent 5938f5a commit 3371080

File tree

2 files changed

+78
-14
lines changed

2 files changed

+78
-14
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 69 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -838,16 +838,21 @@ makeIndirectFieldAccessors(ClangImporter::Implementation &Impl,
838838
auto selfDecl = getterDecl->getImplicitSelfDecl();
839839
Expr *expr = new (C) DeclRefExpr(selfDecl, DeclNameLoc(),
840840
/*implicit*/true);
841+
expr->setType(selfDecl->getInterfaceType());
842+
841843
expr = new (C) MemberRefExpr(expr, SourceLoc(), anonymousFieldDecl,
842844
DeclNameLoc(), /*implicit*/true);
845+
expr->setType(anonymousFieldDecl->getInterfaceType());
843846

844847
expr = new (C) MemberRefExpr(expr, SourceLoc(), anonymousInnerFieldDecl,
845848
DeclNameLoc(), /*implicit*/true);
849+
expr->setType(anonymousInnerFieldDecl->getInterfaceType());
846850

847851
auto ret = new (C) ReturnStmt(SourceLoc(), expr);
848852
auto body = BraceStmt::create(C, SourceLoc(), ASTNode(ret), SourceLoc(),
849853
/*implicit*/ true);
850854
getterDecl->setBody(body);
855+
getterDecl->setBodyTypeCheckedIfPresent();
851856
getterDecl->getAttrs().add(new (C) TransparentAttr(/*implicit*/ true));
852857
Impl.registerExternalDecl(getterDecl);
853858
}
@@ -857,22 +862,29 @@ makeIndirectFieldAccessors(ClangImporter::Implementation &Impl,
857862
auto selfDecl = setterDecl->getImplicitSelfDecl();
858863
Expr *lhs = new (C) DeclRefExpr(selfDecl, DeclNameLoc(),
859864
/*implicit*/true);
865+
lhs->setType(LValueType::get(selfDecl->getInterfaceType()));
866+
860867
lhs = new (C) MemberRefExpr(lhs, SourceLoc(), anonymousFieldDecl,
861-
DeclNameLoc(), /*implicit*/true);
868+
DeclNameLoc(), /*implicit*/true);
869+
lhs->setType(LValueType::get(anonymousFieldDecl->getInterfaceType()));
862870

863871
lhs = new (C) MemberRefExpr(lhs, SourceLoc(), anonymousInnerFieldDecl,
864872
DeclNameLoc(), /*implicit*/true);
873+
lhs->setType(LValueType::get(anonymousInnerFieldDecl->getInterfaceType()));
865874

866875
auto newValueDecl = setterDecl->getParameters()->get(0);
867876

868877
auto rhs = new (C) DeclRefExpr(newValueDecl, DeclNameLoc(),
869878
/*implicit*/ true);
879+
rhs->setType(newValueDecl->getInterfaceType());
870880

871881
auto assign = new (C) AssignExpr(lhs, SourceLoc(), rhs, /*implicit*/true);
882+
assign->setType(TupleType::getEmpty(C));
872883

873884
auto body = BraceStmt::create(C, SourceLoc(), { assign }, SourceLoc(),
874885
/*implicit*/ true);
875886
setterDecl->setBody(body);
887+
setterDecl->setBodyTypeCheckedIfPresent();
876888
setterDecl->getAttrs().add(new (C) TransparentAttr(/*implicit*/ true));
877889
Impl.registerExternalDecl(setterDecl);
878890
}
@@ -922,18 +934,35 @@ makeUnionFieldAccessors(ClangImporter::Implementation &Impl,
922934

923935
auto selfRef = new (C) DeclRefExpr(selfDecl, DeclNameLoc(),
924936
/*implicit*/ true);
937+
selfRef->setType(selfDecl->getInterfaceType());
938+
925939
auto reinterpretCast = cast<FuncDecl>(getBuiltinValueDecl(
926940
C, C.getIdentifier("reinterpretCast")));
927-
auto reinterpretCastRef
928-
= new (C) DeclRefExpr(reinterpretCast, DeclNameLoc(), /*implicit*/ true);
929-
auto reinterpreted = CallExpr::createImplicit(C, reinterpretCastRef,
941+
942+
ConcreteDeclRef reinterpretCastRef(
943+
reinterpretCast,
944+
SubstitutionMap::get(reinterpretCast->getGenericSignature(),
945+
{selfDecl->getInterfaceType(),
946+
importedFieldDecl->getInterfaceType()},
947+
ArrayRef<ProtocolConformanceRef>()));
948+
auto reinterpretCastRefExpr
949+
= new (C) DeclRefExpr(reinterpretCastRef, DeclNameLoc(),
950+
/*implicit*/ true);
951+
reinterpretCastRefExpr->setType(
952+
FunctionType::get(
953+
AnyFunctionType::Param(selfDecl->getInterfaceType()),
954+
importedFieldDecl->getInterfaceType()));
955+
956+
auto reinterpreted = CallExpr::createImplicit(C, reinterpretCastRefExpr,
930957
{ selfRef },
931958
{ Identifier() });
959+
reinterpreted->setType(importedFieldDecl->getInterfaceType());
932960
reinterpreted->setThrows(false);
933961
auto ret = new (C) ReturnStmt(SourceLoc(), reinterpreted);
934962
auto body = BraceStmt::create(C, SourceLoc(), ASTNode(ret), SourceLoc(),
935963
/*implicit*/ true);
936964
getterDecl->setBody(body);
965+
getterDecl->setBodyTypeCheckedIfPresent();
937966
getterDecl->getAttrs().add(new (C) TransparentAttr(/*implicit*/ true));
938967
Impl.registerExternalDecl(getterDecl);
939968
}
@@ -944,30 +973,56 @@ makeUnionFieldAccessors(ClangImporter::Implementation &Impl,
944973

945974
auto inoutSelfRef = new (C) DeclRefExpr(inoutSelfDecl, DeclNameLoc(),
946975
/*implicit*/ true);
976+
inoutSelfRef->setType(LValueType::get(inoutSelfDecl->getInterfaceType()));
947977
auto inoutSelf = new (C) InOutExpr(SourceLoc(), inoutSelfRef,
948978
importedUnionDecl->getDeclaredType(), /*implicit*/ true);
979+
inoutSelf->setType(InOutType::get(inoutSelfDecl->getInterfaceType()));
949980

950981
auto newValueDecl = setterDecl->getParameters()->get(0);
951982

952983
auto newValueRef = new (C) DeclRefExpr(newValueDecl, DeclNameLoc(),
953984
/*implicit*/ true);
985+
newValueRef->setType(newValueDecl->getInterfaceType());
986+
954987
auto addressofFn = cast<FuncDecl>(getBuiltinValueDecl(
955988
C, C.getIdentifier("addressof")));
956-
auto addressofFnRef
957-
= new (C) DeclRefExpr(addressofFn, DeclNameLoc(), /*implicit*/ true);
958-
auto selfPointer = CallExpr::createImplicit(C, addressofFnRef,
989+
ConcreteDeclRef addressofFnRef(addressofFn,
990+
SubstitutionMap::get(addressofFn->getGenericSignature(),
991+
{inoutSelfDecl->getInterfaceType()},
992+
ArrayRef<ProtocolConformanceRef>()));
993+
auto addressofFnRefExpr
994+
= new (C) DeclRefExpr(addressofFnRef, DeclNameLoc(), /*implicit*/ true);
995+
addressofFnRefExpr->setType(
996+
FunctionType::get(AnyFunctionType::Param(inoutSelfDecl->getInterfaceType(),
997+
Identifier(),
998+
ParameterTypeFlags().withInOut(true)),
999+
C.TheRawPointerType));
1000+
auto selfPointer = CallExpr::createImplicit(C, addressofFnRefExpr,
9591001
{ inoutSelf },
9601002
{ Identifier() });
1003+
selfPointer->setType(C.TheRawPointerType);
1004+
9611005
auto initializeFn = cast<FuncDecl>(getBuiltinValueDecl(
9621006
C, C.getIdentifier("initialize")));
963-
auto initializeFnRef
964-
= new (C) DeclRefExpr(initializeFn, DeclNameLoc(), /*implicit*/ true);
965-
auto initialize = CallExpr::createImplicit(C, initializeFnRef,
1007+
ConcreteDeclRef initializeFnRef(initializeFn,
1008+
SubstitutionMap::get(initializeFn->getGenericSignature(),
1009+
{newValueDecl->getInterfaceType()},
1010+
ArrayRef<ProtocolConformanceRef>()));
1011+
auto initializeFnRefExpr
1012+
= new (C) DeclRefExpr(initializeFnRef, DeclNameLoc(), /*implicit*/ true);
1013+
initializeFnRefExpr->setType(
1014+
FunctionType::get({AnyFunctionType::Param(newValueDecl->getInterfaceType()),
1015+
AnyFunctionType::Param(C.TheRawPointerType)},
1016+
TupleType::getEmpty(C)));
1017+
auto initialize = CallExpr::createImplicit(C, initializeFnRefExpr,
9661018
{ newValueRef, selfPointer },
9671019
{ Identifier(), Identifier() });
1020+
initialize->setType(TupleType::getEmpty(C));
1021+
9681022
auto body = BraceStmt::create(C, SourceLoc(), { initialize }, SourceLoc(),
9691023
/*implicit*/ true);
9701024
setterDecl->setBody(body);
1025+
setterDecl->setBodyTypeCheckedIfPresent();
9711026
setterDecl->getAttrs().add(new (C) TransparentAttr(/*implicit*/ true));
9721027
Impl.registerExternalDecl(setterDecl);
9731028
}
@@ -1833,6 +1888,8 @@ static bool addErrorDomain(NominalTypeDecl *swiftDecl,
18331888

18341889
DeclRefExpr *domainDeclRef = new (C)
18351890
DeclRefExpr(ConcreteDeclRef(swiftValueDecl), {}, isImplicit);
1891+
domainDeclRef->setType(swiftValueDecl->getInterfaceType());
1892+
18361893
auto *params = ParameterList::createEmpty(C);
18371894

18381895
auto getterDecl = AccessorDecl::create(C,
@@ -1864,6 +1921,8 @@ static bool addErrorDomain(NominalTypeDecl *swiftDecl,
18641921
auto ret = new (C) ReturnStmt(SourceLoc(), domainDeclRef);
18651922
getterDecl->setBody(
18661923
BraceStmt::create(C, SourceLoc(), {ret}, SourceLoc(), isImplicit));
1924+
getterDecl->setBodyTypeCheckedIfPresent();
1925+
18671926
importer.registerExternalDecl(getterDecl);
18681927
return true;
18691928
}

test/ClangImporter/ctypes_parse_union.swift

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
1-
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify %s
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-ir %s
22

33
import ctypes
44

5-
func useStructWithUnion(_ vec: GLKVector4) -> GLKVector4 {
5+
func useStructWithUnion(_ vec: GLKVector4) {
66
var vec = vec
77
_ = vec.v.0
88
_ = vec.v.1
99
_ = vec.v.2
1010
_ = vec.v.3
1111

1212
vec.v = (0, 0, 0, 0)
13+
1314
}
1415

1516
func useUnionIndirectFields(_ vec: GLKVector4) -> GLKVector4 {
@@ -33,7 +34,11 @@ func useUnionIndirectFields(_ vec: GLKVector4) -> GLKVector4 {
3334
let _: CFloat = vec.v.1
3435
let _: CFloat = vec.v.2
3536
let _: CFloat = vec.v.3
36-
return vec
37+
38+
var vec1 = vec
39+
vec1.x = vec.y
40+
41+
return vec1
3742
}
3843

3944
func useStructWithNamedUnion(_ u: NamedUnion) -> NamedUnion {
@@ -53,7 +58,7 @@ func useStructWithAnonymousUnion(_ u: AnonUnion) -> AnonUnion {
5358
return u
5459
}
5560

56-
func useStructWithUnnamedUnion(_ u: UnnamedUnion) -> UnnamedUnion {
61+
func useStructWithUnnamedUnion(_ u: UnnamedUnion) {
5762
var u = u
5863
u.u.i = 100
5964
u.u.f = 1.0

0 commit comments

Comments
 (0)