Skip to content

Commit bb0ac20

Browse files
authored
Merge pull request #7770 from slavapestov/irgen-cleanup-and-crashers
IRGen cleanup and crashers
2 parents 17da6b3 + da53c3d commit bb0ac20

File tree

14 files changed

+117
-62
lines changed

14 files changed

+117
-62
lines changed

include/swift/AST/Types.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -882,13 +882,15 @@ class alignas(1 << TypeAlignInBits) TypeBase {
882882
/// Get the substitutions to apply to the type of the given member as seen
883883
/// from this base type.
884884
///
885-
/// If the member has its own generic parameters, they will remain unchanged
886-
/// by the substitution.
885+
/// \param genericEnv If non-null, generic parameters of the member are
886+
/// mapped to context archetypes of this generic environment.
887887
SubstitutionMap getMemberSubstitutionMap(ModuleDecl *module,
888-
const ValueDecl *member);
888+
const ValueDecl *member,
889+
GenericEnvironment *genericEnv=nullptr);
889890

890891
/// Deprecated version of the above.
891-
TypeSubstitutionMap getMemberSubstitutions(const ValueDecl *member);
892+
TypeSubstitutionMap getMemberSubstitutions(const ValueDecl *member,
893+
GenericEnvironment *genericEnv=nullptr);
892894

893895
/// Retrieve the type of the given member as seen through the given base
894896
/// type, substituting generic arguments where necessary.

lib/AST/Type.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "swift/AST/TypeWalker.h"
2121
#include "swift/AST/Decl.h"
2222
#include "swift/AST/AST.h"
23+
#include "swift/AST/GenericEnvironment.h"
2324
#include "swift/AST/LazyResolver.h"
2425
#include "swift/AST/Module.h"
2526
#include "swift/AST/SubstitutionMap.h"
@@ -3240,7 +3241,7 @@ TypeSubstitutionMap TypeBase::getContextSubstitutions(const DeclContext *dc) {
32403241
}
32413242

32423243
SubstitutionMap TypeBase::getContextSubstitutionMap(
3243-
ModuleDecl *module, const DeclContext *dc) {
3244+
ModuleDecl *module, const DeclContext *dc) {
32443245
auto *genericSig = dc->getGenericSignatureOfContext();
32453246
if (genericSig == nullptr)
32463247
return SubstitutionMap();
@@ -3249,7 +3250,9 @@ SubstitutionMap TypeBase::getContextSubstitutionMap(
32493250
LookUpConformanceInModule(module));
32503251
}
32513252

3252-
TypeSubstitutionMap TypeBase::getMemberSubstitutions(const ValueDecl *member) {
3253+
TypeSubstitutionMap TypeBase::getMemberSubstitutions(
3254+
const ValueDecl *member,
3255+
GenericEnvironment *genericEnv) {
32533256
auto *memberDC = member->getDeclContext();
32543257

32553258
TypeSubstitutionMap substitutions;
@@ -3262,14 +3265,18 @@ TypeSubstitutionMap TypeBase::getMemberSubstitutions(const ValueDecl *member) {
32623265
// We need this since code completion and diagnostics want to be able
32633266
// to call getTypeOfMember() with functions and nested types.
32643267
if (isa<AbstractFunctionDecl>(member) ||
3265-
isa<GenericTypeDecl>(member)) {
3268+
isa<GenericTypeDecl>(member) ||
3269+
isa<SubscriptDecl>(member)) {
32663270
auto *innerDC = member->getInnermostDeclContext();
32673271
if (innerDC->isInnermostContextGeneric()) {
32683272
auto *sig = innerDC->getGenericSignatureOfContext();
32693273
for (auto param : sig->getInnermostGenericParams()) {
32703274
auto *genericParam = param->getCanonicalType()
32713275
->castTo<GenericTypeParamType>();
3272-
substitutions[genericParam] = param;
3276+
substitutions[genericParam] =
3277+
(genericEnv
3278+
? genericEnv->mapTypeIntoContext(param)
3279+
: param);
32733280
}
32743281
}
32753282
}
@@ -3278,13 +3285,15 @@ TypeSubstitutionMap TypeBase::getMemberSubstitutions(const ValueDecl *member) {
32783285
}
32793286

32803287
SubstitutionMap TypeBase::getMemberSubstitutionMap(
3281-
ModuleDecl *module, const ValueDecl *member) {
3288+
ModuleDecl *module, const ValueDecl *member,
3289+
GenericEnvironment *genericEnv) {
32823290
auto *genericSig = member->getInnermostDeclContext()
32833291
->getGenericSignatureOfContext();
32843292
if (genericSig == nullptr)
32853293
return SubstitutionMap();
3294+
auto subs = getMemberSubstitutions(member, genericEnv);
32863295
return genericSig->getSubstitutionMap(
3287-
QueryTypeSubstitutionMap{getMemberSubstitutions(member)},
3296+
QueryTypeSubstitutionMap{subs},
32883297
LookUpConformanceInModule(module));
32893298
}
32903299

lib/IRGen/GenFunc.cpp

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,7 @@ const TypeInfo *TypeConverter::convertFunctionType(SILFunctionType *T) {
555555

556556
case SILFunctionType::Representation::Thin:
557557
case SILFunctionType::Representation::Method:
558+
case SILFunctionType::Representation::WitnessMethod:
558559
case SILFunctionType::Representation::ObjCMethod:
559560
case SILFunctionType::Representation::CFunctionPointer:
560561
case SILFunctionType::Representation::Closure:
@@ -576,19 +577,6 @@ const TypeInfo *TypeConverter::convertFunctionType(SILFunctionType *T) {
576577
std::move(spareBits),
577578
IsNotPOD);
578579
}
579-
// Witness method values carry a reference to their originating witness table
580-
// as context.
581-
case SILFunctionType::Representation::WitnessMethod: {
582-
SpareBitVector spareBits;
583-
spareBits.append(IGM.getFunctionPointerSpareBits());
584-
spareBits.append(IGM.getWitnessTablePtrSpareBits());
585-
return FuncTypeInfo::create(CanSILFunctionType(T),
586-
IGM.WitnessFunctionPairTy,
587-
IGM.getPointerSize() * 2,
588-
IGM.getPointerAlignment(),
589-
std::move(spareBits),
590-
IsPOD);
591-
}
592580
}
593581
llvm_unreachable("bad function type representation");
594582
}

lib/IRGen/GenProto.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2747,7 +2747,6 @@ irgen::emitWitnessMethodValue(IRGenFunction &IGF,
27472747

27482748
// Build the value.
27492749
out.add(witness);
2750-
out.add(wtable);
27512750
}
27522751

27532752
llvm::FunctionType *IRGenModule::getAssociatedTypeMetadataAccessFunctionTy() {

lib/IRGen/IRGenModule.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,10 +273,6 @@ IRGenModule::IRGenModule(IRGenerator &irgen,
273273
FunctionPtrTy,
274274
RefCountedPtrTy,
275275
});
276-
WitnessFunctionPairTy = createStructType(*this, "swift.function", {
277-
FunctionPtrTy,
278-
WitnessTablePtrTy,
279-
});
280276

281277
OpaquePtrTy = llvm::StructType::create(LLVMContext, "swift.opaque")
282278
->getPointerTo(DefaultAS);

lib/IRGen/IRGenModule.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,6 @@ class IRGenModule {
430430
llvm::PointerType *UnownedReferencePtrTy;/// %swift.unowned_reference*
431431
llvm::Constant *RefCountedNull; /// %swift.refcounted* null
432432
llvm::StructType *FunctionPairTy; /// { i8*, %swift.refcounted* }
433-
llvm::StructType *WitnessFunctionPairTy; /// { i8*, %witness.table* }
434433
llvm::FunctionType *DeallocatingDtorTy; /// void (%swift.refcounted*)
435434
llvm::StructType *TypeMetadataStructTy; /// %swift.type = type { ... }
436435
llvm::PointerType *TypeMetadataPtrTy;/// %swift.type*

lib/IRGen/IRGenSIL.cpp

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,12 +1992,8 @@ static CallEmission getCallEmissionForLoweredValue(IRGenSILFunction &IGF,
19921992

19931993
if (origCalleeType->getRepresentation()
19941994
== SILFunctionType::Representation::WitnessMethod) {
1995-
// @convention(witness_method) callees are exploded as a
1996-
// triple consisting of the function, Self metadata, and
1997-
// the Self witness table.
1998-
witnessMetadata->SelfWitnessTable = calleeValues.claimNext();
1999-
assert(witnessMetadata->SelfWitnessTable->getType() ==
2000-
IGF.IGM.WitnessTablePtrTy);
1995+
witnessMetadata->SelfWitnessTable = emitWitnessTableForLoweredCallee(
1996+
IGF, origCalleeType, substitutions);
20011997
}
20021998

20031999
if (origCalleeType->getRepresentation()
@@ -2221,12 +2217,9 @@ getPartialApplicationFunction(IRGenSILFunction &IGF, SILValue v,
22212217
case SILFunctionType::Representation::Closure:
22222218
case SILFunctionType::Representation::ObjCMethod:
22232219
break;
2224-
case SILFunctionType::Representation::WitnessMethod: {
2225-
llvm::Value *wtable = ex.claimNext();
2226-
assert(wtable->getType() == IGF.IGM.WitnessTablePtrTy);
2227-
context = wtable;
2220+
case SILFunctionType::Representation::WitnessMethod:
2221+
context = emitWitnessTableForLoweredCallee(IGF, fnType, subs);
22282222
break;
2229-
}
22302223
case SILFunctionType::Representation::CFunctionPointer:
22312224
break;
22322225
case SILFunctionType::Representation::Thick:

test/IRGen/class_bounded_generics.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,9 @@ func class_bounded_archetype_method<T : ClassBoundBinary>(_ x: T, y: T) {
8888
// CHECK: [[INHERITED:%.*]] = load i8*, i8** %T.ClassBoundBinary, align 8
8989
// CHECK: [[INHERITED_WTBL:%.*]] = bitcast i8* [[INHERITED]] to i8**
9090
// CHECK: [[WITNESS:%.*]] = load i8*, i8** [[INHERITED_WTBL]], align 8
91+
// FIXME: Redundant load of inherited conformance
92+
// CHECK: [[INHERITED:%.*]] = load i8*, i8** %T.ClassBoundBinary, align 8
93+
// CHECK: [[INHERITED_WTBL:%.*]] = bitcast i8* [[INHERITED]] to i8**
9194
// CHECK: [[WITNESS_FUNC:%.*]] = bitcast i8* [[WITNESS]] to void (%objc_object*, %swift.type*, i8**)
9295
// CHECK: call swiftcc void [[WITNESS_FUNC]](%objc_object* swiftself %0, %swift.type* {{.*}}, i8** [[INHERITED_WTBL]])
9396
x.classBoundBinaryMethod(y)

test/IRGen/function_types.sil

Lines changed: 15 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
1-
// RUN: %swift -target x86_64-apple-macosx10.9 -module-name function_types %s -emit-ir -o - | %FileCheck %s
2-
// RUN: %swift -target i386-apple-ios7.1 %s -module-name function_types -emit-ir -o - | %FileCheck %s
3-
// RUN: %swift -target x86_64-apple-ios7.1 %s -module-name function_types -emit-ir -o - | %FileCheck %s
4-
// RUN: %swift -target armv7-apple-ios7.1 %s -module-name function_types -emit-ir -o - | %FileCheck %s
5-
// RUN: %swift -target arm64-apple-ios7.1 %s -module-name function_types -emit-ir -o - | %FileCheck %s
6-
// RUN: %swift -target x86_64-unknown-linux-gnu -disable-objc-interop %s -module-name function_types -emit-ir -o - | %FileCheck %s
1+
// RUN: %swift -target x86_64-apple-macosx10.9 -module-name function_types -assume-parsing-unqualified-ownership-sil %s -emit-ir -o - | %FileCheck %s
2+
// RUN: %swift -target i386-apple-ios7.1 %s -module-name function_types -assume-parsing-unqualified-ownership-sil -emit-ir -o - | %FileCheck %s
3+
// RUN: %swift -target x86_64-apple-ios7.1 %s -module-name function_types -assume-parsing-unqualified-ownership-sil -emit-ir -o - | %FileCheck %s
4+
// RUN: %swift -target armv7-apple-ios7.1 %s -module-name function_types -assume-parsing-unqualified-ownership-sil -emit-ir -o - | %FileCheck %s
5+
// RUN: %swift -target arm64-apple-ios7.1 %s -module-name function_types -assume-parsing-unqualified-ownership-sil -emit-ir -o - | %FileCheck %s
6+
// RUN: %swift -target x86_64-unknown-linux-gnu -disable-objc-interop %s -module-name function_types -assume-parsing-unqualified-ownership-sil -emit-ir -o - | %FileCheck %s
77

88
// REQUIRES: CODEGENERATOR=X86
99
// REQUIRES: CODEGENERATOR=ARM
1010

11-
// FIXME: SR-3603 test is failing after being unintentionally disabled for a while
12-
// REQUIRES: SR3603
13-
1411
import Builtin
1512

1613
sil_stage canonical
1714

18-
// CHECK-LABEL: define{{( protected)?}} i8* @thin_func_value(i8*) {{.*}} {
15+
// CHECK-LABEL: define{{( protected)?}} swiftcc i8* @thin_func_value(i8*) {{.*}} {
1916
// CHECK-NEXT: entry:
2017
// CHECK-NEXT: ret i8* %0
2118
// CHECK-NEXT: }
@@ -24,7 +21,7 @@ entry(%x : $@convention(thin) () -> ()):
2421
return %x : $@convention(thin) () -> ()
2522
}
2623

27-
// CHECK-LABEL: define{{( protected)?}} { i8*, %swift.refcounted* } @thick_func_value(i8*, %swift.refcounted*) {{.*}} {
24+
// CHECK-LABEL: define{{( protected)?}} swiftcc { i8*, %swift.refcounted* } @thick_func_value(i8*, %swift.refcounted*) {{.*}} {
2825
// CHECK-NEXT: entry:
2926
// CHECK-NEXT: call void @swift_rt_swift_retain(%swift.refcounted* %1) {{#[0-9]+}}
3027
// CHECK-NEXT: call void @swift_rt_swift_release(%swift.refcounted* %1) {{#[0-9]+}}
@@ -39,11 +36,9 @@ entry(%x : $() -> ()):
3936
return %x : $() -> ()
4037
}
4138

42-
// CHECK-LABEL: define{{( protected)?}} { i8*, i8** } @thin_witness_value(i8*, i8**) {{.*}} {
39+
// CHECK-LABEL: define{{( protected)?}} swiftcc i8* @thin_witness_value(i8*) {{.*}} {
4340
// CHECK-NEXT: entry:
44-
// CHECK-NEXT: [[T0:%.*]] = insertvalue { i8*, i8** } undef, i8* %0, 0
45-
// CHECK-NEXT: [[T1:%.*]] = insertvalue { i8*, i8** } [[T0]], i8** %1, 1
46-
// CHECK-NEXT: ret { i8*, i8** } [[T1]]
41+
// CHECK-NEXT: ret i8* %0
4742
// CHECK-NEXT: }
4843
sil @thin_witness_value : $@convention(thin) (@convention(witness_method) () -> ()) -> @convention(witness_method) () -> () {
4944
entry(%x : $@convention(witness_method) () -> ()):
@@ -54,9 +49,9 @@ struct X {}
5449

5550
sil @out_void_return : $@convention(thin) () -> @out X
5651

57-
// CHECK-LABEL: define{{( protected)?}} void @use_void_return_value(%V14function_types1X* noalias nocapture sret) {{.*}} {
52+
// CHECK-LABEL: define{{( protected)?}} swiftcc void @use_void_return_value(%T14function_types1XV* noalias nocapture sret) {{.*}} {
5853
// CHECK-NEXT: entry:
59-
// CHECK-NEXT: call void @out_void_return(%V14function_types1X* noalias nocapture sret %0)
54+
// CHECK-NEXT: call swiftcc void @out_void_return(%T14function_types1XV* noalias nocapture sret %0)
6055
// CHECK-NEXT: ret void
6156
// CHECK-NEXT: }
6257
sil @use_void_return_value : $@convention(thin) () -> @out X {
@@ -66,7 +61,7 @@ entry(%x : $*X):
6661
return %z : $()
6762
}
6863

69-
// CHECK-LABEL: define{{( protected)?}} i1 @test_is_nonnull_function(i8*, %swift.refcounted*) {{.*}} {
64+
// CHECK-LABEL: define{{( protected)?}} swiftcc i1 @test_is_nonnull_function(i8*, %swift.refcounted*) {{.*}} {
7065
// CHECK-NEXT: entry:
7166
// CHECK-NEXT: %2 = icmp ne i8* %0, null
7267
// CHECK-NEXT: ret i1 %2
@@ -78,7 +73,7 @@ bb0(%0 : $() -> ()):
7873
return %3 : $Builtin.Int1 // id: %5
7974
}
8075

81-
// CHECK-LABEL: define{{( protected)?}} i8* @test_function_to_pointer(i8*)
76+
// CHECK-LABEL: define{{( protected)?}} swiftcc i8* @test_function_to_pointer(i8*)
8277
// CHECK-NEXT: entry:
8378
// CHECK-NEXT: ret i8* %0
8479
sil @test_function_to_pointer : $@convention(thin) (@convention(thin) () -> ()) -> Builtin.RawPointer {
@@ -87,7 +82,7 @@ bb0(%0 : $@convention(thin) () -> ()):
8782
return %1 : $Builtin.RawPointer
8883
}
8984

90-
// CHECK-LABEL: define{{( protected)?}} i8* @test_pointer_to_function(i8*)
85+
// CHECK-LABEL: define{{( protected)?}} swiftcc i8* @test_pointer_to_function(i8*)
9186
// CHECK-NEXT: entry:
9287
// CHECK-NEXT: ret i8* %0
9388
sil @test_pointer_to_function : $@convention(thin) (Builtin.RawPointer) -> @convention(thin) () -> () {

test/IRGen/sil_witness_methods.sil

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ entry(%z : $*Z, %x : $*Foo):
8585
return %m : $@thick Foo.Type
8686
}
8787

88-
// CHECK-LABEL: define{{( protected)?}} swiftcc %swift.type* @generic_type_generic_method_witness(%swift.opaque* noalias nocapture, %swift.type* %Z, %T19sil_witness_methods3BarC{{(.1)?}}** noalias nocapture swiftself dereferenceable(8), %swift.type* %Self, i8** %SelfWitnessTable)
88+
// CHECK-LABEL: define{{( protected)?}} swiftcc %swift.type* @generic_type_generic_method_witness(%swift.opaque* noalias nocapture, %swift.type* %Z, %T19sil_witness_methods3BarC{{.*}}** noalias nocapture swiftself dereferenceable(8), %swift.type* %Self, i8** %SelfWitnessTable)
8989
sil @generic_type_generic_method_witness : $@convention(witness_method) <T, U, V, Z> (@in Z, @in Bar<T, U, V>) -> @thick Bar<T, U, V>.Type {
9090
entry(%z : $*Z, %x : $*Bar<T, U, V>):
9191
%t = metatype $@thick T.Type

test/IRGen/witness_method_phi.sil

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ entry:
1010
br bb1(%1 : $@convention(witness_method) <T: P> (@in P) -> ())
1111

1212
// CHECK: phi i8* [ %0, %entry ]
13-
// CHECK-NEXT: phi i8** [ %T.P, %entry ]
1413
bb1(%2 : $@convention(witness_method) <T: P> (@in P) -> ()):
1514
unreachable
1615
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: not --crash %target-swift-frontend %s -emit-ir
2+
// REQUIRES: asserts
3+
4+
class PropertyDataSource<O: PropertyHosting> {
5+
}
6+
7+
protocol TableViewCellFactoryType {
8+
associatedtype Item
9+
}
10+
11+
public protocol PropertyHosting {
12+
associatedtype PType: Hashable, EntityOwned
13+
}
14+
15+
public protocol EntityOwned: class {
16+
associatedtype Owner
17+
}
18+
19+
public protocol PropertyType: class {
20+
}
21+
22+
func useType<T>(cellType: T.Type) {
23+
}
24+
25+
final class PropertyTableViewAdapter<Factory: TableViewCellFactoryType>
26+
where
27+
Factory.Item: PropertyType,
28+
Factory.Item.Owner: PropertyHosting,
29+
Factory.Item.Owner.PType == Factory.Item
30+
{
31+
typealias Item = Factory.Item
32+
33+
let dataManager: PropertyDataSource<Factory.Item.Owner>
34+
init(dataManager: PropertyDataSource<Factory.Item.Owner>) {
35+
useType(cellType: Factory.Item.Owner.self)
36+
self.dataManager = dataManager
37+
}
38+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: not --crash %target-swift-frontend %s -emit-ir
2+
3+
protocol A {
4+
associatedtype Coordinate: Strideable
5+
func doSomething(_: Range<Coordinate>) -> Coordinate.Stride
6+
}
7+
8+
extension A where Coordinate == Int {
9+
func extensionFunc(_ range: Range<Coordinate>) {
10+
_ = doSomething(range)
11+
}
12+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %target-swift-frontend %s -emit-ir
2+
3+
protocol DataSourceItem { }
4+
5+
protocol TableDataSourceItem : DataSourceItem { }
6+
7+
8+
class DataSource<T : DataSourceItem> { }
9+
10+
class TableDataSource<T : TableDataSourceItem>: DataSource<T> { }
11+
12+
13+
class DataSourceBuilder<T : TableDataSourceItem, U : TableDataSource<T>> { }
14+
15+
class TableDataSourceBuilder<T : TableDataSourceItem, U : TableDataSource<T>> : DataSourceBuilder<T, U> { }
16+
17+
18+
enum MyItem: TableDataSourceItem { }
19+
20+
class MyBuilder : TableDataSourceBuilder<MyItem, TableDataSource<MyItem>> { }
21+
22+
let builder = MyBuilder()

0 commit comments

Comments
 (0)