Skip to content

[test] Change stored-properties-client to an executable test #21426

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
164 changes: 53 additions & 111 deletions test/ParseableInterface/stored-properties-client.swift
Original file line number Diff line number Diff line change
@@ -1,145 +1,87 @@
// RUN: %empty-directory(%t)

// RUN: %target-swift-frontend -typecheck %S/stored-properties.swift -module-name StoredProperties -emit-parseable-module-interface-path %t/StoredProperties.swiftinterface
// RUN: %target-swift-frontend -emit-ir %s -I %t | %FileCheck %s -check-prefix CHECK -check-prefix COMMON
// 1. Build ../stored-properties.swift to a dylib and emit its interface in %t

// RUN: %target-swift-frontend -typecheck %S/stored-properties.swift -enable-library-evolution -module-name StoredProperties -emit-parseable-module-interface-path %t/StoredProperties.swiftinterface
// RUN: %target-swift-frontend -emit-ir %s -I %t | %FileCheck %s -check-prefix RESILIENT -check-prefix COMMON
// RUN: %target-build-swift-dylib(%t/%target-library-name(StoredProperties)) -emit-module-interface-path %t/StoredProperties.swiftinterface %S/stored-properties.swift -module-name StoredProperties -swift-version 5

// REQUIRES: rdar_46486517
// 2. Build this file and link with StoredProperties

import StoredProperties

/// This test makes sure clients of a parseable interface see correct type
/// layout and use the right access patterns in the presence of a
/// .swiftinterface file, in both resilient and non-resilient cases.
// RUN: %target-build-swift %s -I %t -L %t -lStoredProperties -o %t/stored-properties-client %target-rpath(%t)

// COMMON: %[[BAGOFVARIABLES:T16StoredProperties14BagOfVariablesV]] = type <{ %TSi, %TSb, [{{(3|7)}} x i8], %TSi }>
// 3. Codesign and run this, and ensure it exits successfully.

// This type is non-@_fixed_layout, so it becomes opaque in a resilient module
// CHECK: %[[HASSTOREDPROPERTIES:T16StoredProperties03HasaB0V]] = type <{ %TSi, %TSi, %TSb, [{{(3|7)}} x i8], %TSi, %TSb, [{{3|7}} x i8], %TSi }>
// RESILIENT: %[[HASSTOREDPROPERTIES:swift.opaque]] = type opaque
// RUN: %target-codesign %t/stored-properties-client %t/%target-library-name(StoredProperties)
// RUN: %target-run %t/stored-properties-client %t/%target-library-name(StoredProperties)

// COMMON: %[[HASSTOREDPROPERTIESFIXEDLAYOUT:T16StoredProperties03HasaB11FixedLayoutV]] = type <{ %[[BAGOFVARIABLES]], %[[BAGOFVARIABLES]] }>
// 4. Repeat these steps, with library evolution enabled.

// These are here just to make sure the compiler doesn't optimize away accesses.
// They're overloaded instead of generic so we avoid generic dispatch.
// RUN: %empty-directory(%t)

@inline(never)
func _blackHole(_ value: Int) {}
// RUN: %target-build-swift-dylib(%t/%target-library-name(StoredProperties)) -emit-module-interface-path %t/StoredProperties.swiftinterface %S/stored-properties.swift -module-name StoredProperties -swift-version 5 -enable-library-evolution

@inline(never)
func _blackHole(_ value: Bool) {}
// RUN: %target-build-swift %s -I %t -L %t -lStoredProperties -o %t/stored-properties-client %target-rpath(%t)
// RUN: %target-codesign %t/stored-properties-client %t/%target-library-name(StoredProperties)
// RUN: %target-run %t/stored-properties-client %t/%target-library-name(StoredProperties)

@inline(never)
func _blackHole(_ value: BagOfVariables) {}
import StdlibUnittest
import StoredProperties

/// In the following code, getting and setting is split because otherwise
/// the resulting IR is ordered differently.
/// This test makes sure clients of a parseable interface see correct type
/// layout and use the right access patterns in the presence of a
/// .swiftinterface file, in both resilient and non-resilient cases.

/// Test that we call the correct accessors in a resilient module, and that
/// we use trivial storage accesses in a non-resilient module.

func testGetting() {
// CHECK: %[[VALUE:.*]] = alloca %[[HASSTOREDPROPERTIES]]
// CHECK: call swiftcc void @"$s16StoredProperties03HasaB0VACycfC"(%[[HASSTOREDPROPERTIES]]* {{.*}} %[[VALUE]])
// RESILIENT: %[[VALUE:.*]] = alloca i8, [[WORD:i[0-9]+]] %size
// RESILIENT: %[[VALUECAST:.*]] = bitcast i8* %value to %[[HASSTOREDPROPERTIES]]*
// RESILIENT: call swiftcc void @"$s16StoredProperties03HasaB0VACycfC"(%[[HASSTOREDPROPERTIES]]* noalias nocapture sret %[[VALUECAST]])
var value = HasStoredProperties()

// CHECK: getelementptr inbounds %[[HASSTOREDPROPERTIES]], %[[HASSTOREDPROPERTIES]]* %[[VALUE]], i32 0, i32 1
// CHECK: getelementptr inbounds %[[HASSTOREDPROPERTIES]], %[[HASSTOREDPROPERTIES]]* %[[VALUE]], i32 0, i32 2

// These are accessed in declaration order so the IR is emitted in the same
// order.

// COMMON: call swiftcc [[WORD:i[0-9]+]] @"$s16StoredProperties03HasaB0V14computedGetterSivg"
_blackHole(value.computedGetter)

// COMMON: call swiftcc [[WORD]] @"$s16StoredProperties03HasaB0V14computedGetSetSivg"
_blackHole(value.computedGetSet)

// CHECK: getelementptr inbounds %[[HASSTOREDPROPERTIES]], %[[HASSTOREDPROPERTIES]]* %[[VALUE]], i32 0, i32 0
// CHECK: getelementptr inbounds %[[HASSTOREDPROPERTIES]], %[[HASSTOREDPROPERTIES]]* %[[VALUE]], i32 0, i32 4

// RESILIENT: call swiftcc [[WORD]] @"$s16StoredProperties03HasaB0V06simpleA9ImmutableSivg"
_blackHole(value.simpleStoredImmutable)
var StoredPropertyTests = TestSuite("StoredProperty")

// RESILIENT: call swiftcc [[WORD]] @"$s16StoredProperties03HasaB0V06simpleA7MutableSivg"
_blackHole(value.simpleStoredMutable)

// RESILIENT: call swiftcc i1 @"$s16StoredProperties03HasaB0V19storedWithObserversSbvg"
_blackHole(value.storedWithObservers)

// RESILIENT: call swiftcc [[WORD]] @"$s16StoredProperties03HasaB0V16storedPrivateSetSivg"
_blackHole(value.storedPrivateSet)
StoredPropertyTests.test("Getting/NonFixedLayout") {
var value = HasStoredProperties()
expectEqual(3, value.computedGetter)
expectEqual(3, value.computedGetSet)
expectEqual(0, value.simpleStoredImmutable)
expectEqual(0, value.simpleStoredMutable)
expectEqual(false, value.storedWithObservers)
expectEqual(0, value.storedPrivateSet)
}

func testSetting() {
// CHECK: call swiftcc void @"$s16StoredProperties03HasaB0VACycfC"(%[[HASSTOREDPROPERTIES]]* {{.*}})
// RESILIENT: call swiftcc %swift.metadata_response @"$s16StoredProperties03HasaB0VMa"([[WORD]] 0)
// RESILIENT: %[[VALUEALLOC:.*]] = alloca i8, [[WORD]] %size
// RESILIENT: bitcast i8* %[[VALUEALLOC]] to %[[HASSTOREDPROPERTIES]]*
StoredPropertyTests.test("Setting/NonFixedLayout") {
var value = HasStoredProperties()

// COMMON: call swiftcc void @"$s16StoredProperties03HasaB0V19storedWithObserversSbvs"(i1 false, %[[HASSTOREDPROPERTIES]]* {{.*}})
value.storedWithObservers = false

// COMMON-NEXT: call swiftcc void @"$s16StoredProperties03HasaB0V14computedGetSetSivs"([[WORD]] 4, %[[HASSTOREDPROPERTIES]]* {{.*}})
value.storedWithObservers = true
value.computedGetSet = 4

// CHECK: %[[MUTABLE_PTR:.*]] = getelementptr inbounds %[[HASSTOREDPROPERTIES]], %[[HASSTOREDPROPERTIES]]* {{.*}}, i32 0, i32 1
// CHECK: %[[MUTABLE_INT_PTR:.*]] = getelementptr inbounds %TSi, %TSi* %[[MUTABLE_PTR]], i32 0, i32 0
// CHECK: store [[WORD]] 4, [[WORD]]* %[[MUTABLE_INT_PTR]]
// RESILIENT: call swiftcc void @"$s16StoredProperties03HasaB0V06simpleA7MutableSivs"([[WORD]] 4, %[[HASSTOREDPROPERTIES]]* {{.*}})
value.simpleStoredMutable = 4
}

testGetting()
testSetting()

/// Test that we always use trivial access patterns for @_fixed_layout types
/// in resilient or non-resilient modules.
expectEqual(3, value.computedGetter)
expectEqual(3, value.computedGetSet)
expectEqual(0, value.simpleStoredImmutable)
expectEqual(4, value.simpleStoredMutable)
expectEqual(true, value.storedWithObservers)
expectEqual(0, value.storedPrivateSet)
}

func testFixedLayoutGetting() {
// COMMON: %[[VALUEALLOCA:.*]] = alloca %[[HASSTOREDPROPERTIESFIXEDLAYOUT]]
// COMMON: call swiftcc void @"$s16StoredProperties03HasaB11FixedLayoutVACycfC"(%[[HASSTOREDPROPERTIESFIXEDLAYOUT]]* {{.*}} %[[VALUEALLOCA]])
StoredPropertyTests.test("Getting/FixedLayout") {
var value = HasStoredPropertiesFixedLayout()
expectEqual(0, value.simpleStoredMutable.a)
expectEqual(false, value.simpleStoredMutable.b)
expectEqual(0, value.simpleStoredMutable.c)

// These next two tests just make sure we don't use resilient access patterns
// for these fixed_layout structs.

// COMMON: getelementptr inbounds %[[HASSTOREDPROPERTIESFIXEDLAYOUT]], %[[HASSTOREDPROPERTIESFIXEDLAYOUT]]* %[[VALUEALLOCA]], i32 0, i32 0
// COMMON: getelementptr inbounds %[[HASSTOREDPROPERTIESFIXEDLAYOUT]], %[[HASSTOREDPROPERTIESFIXEDLAYOUT]]* %[[VALUEALLOCA]], i32 0, i32 1

// COMMON: call swiftcc void @"$s4main10_blackHoleyy16StoredProperties14BagOfVariablesVF"([[WORD]] %{{.*}}, i1 %{{.*}}, [[WORD]] %{{.*}})
_blackHole(value.simpleStoredMutable)

// COMMON: call swiftcc void @"$s4main10_blackHoleyy16StoredProperties14BagOfVariablesVF"([[WORD]] %{{.*}}, i1 %{{.*}}, [[WORD]] %{{.*}})
_blackHole(value.storedWithObservers)
expectEqual(0, value.storedWithObservers.a)
expectEqual(false, value.storedWithObservers.b)
expectEqual(0, value.storedWithObservers.c)
}

func testFixedLayoutSetting() {
// COMMON: %[[VALUEALLOCA:.*]] = alloca %[[HASSTOREDPROPERTIESFIXEDLAYOUT]]
// COMMON: call swiftcc void @"$s16StoredProperties03HasaB11FixedLayoutVACycfC"(%[[HASSTOREDPROPERTIESFIXEDLAYOUT]]* {{.*}} %[[VALUEALLOCA]])
StoredPropertyTests.test("Setting/FixedLayout") {
var value = HasStoredPropertiesFixedLayout()

// COMMON: call swiftcc void @"$s16StoredProperties03HasaB11FixedLayoutV19storedWithObserversAA14BagOfVariablesVvs"
value.storedWithObservers = BagOfVariables()

// COMMON: %[[PROP:.*]] = getelementptr inbounds %[[HASSTOREDPROPERTIESFIXEDLAYOUT]], %[[HASSTOREDPROPERTIESFIXEDLAYOUT]]* %value, i32 0, i32 0
// COMMON: %[[PROPA:.*]] = getelementptr inbounds %[[BAGOFVARIABLES]], %[[BAGOFVARIABLES]]* %[[PROP]], i32 0, i32 0
// COMMON: %[[PROPAVAL:.*]] = getelementptr inbounds %TSi, %TSi* %[[PROPA]], i32 0, i32 0
// COMMON: store [[WORD]] {{.*}} %[[PROPAVAL]]
// COMMON: %[[PROPB:.*]] = getelementptr inbounds %[[BAGOFVARIABLES]], %[[BAGOFVARIABLES]]* %[[PROP]], i32 0, i32 1
// COMMON: %[[PROPBVAL:.*]] = getelementptr inbounds %TSb, %TSb* %[[PROPB]], i32 0, i32 0
// COMMON: store i1 {{.*}} %[[PROPBVAL]]
// COMMON: %[[PROPC:.*]] = getelementptr inbounds %[[BAGOFVARIABLES]], %[[BAGOFVARIABLES]]* %[[PROP]], i32 0, i32 3
// COMMON: %[[PROPCVAL:.*]] = getelementptr inbounds %TSi, %TSi* %[[PROPC]], i32 0, i32 0
// COMMON: store [[WORD]] {{.*}} %[[PROPCVAL]]
value.simpleStoredMutable = BagOfVariables()
expectEqual(0, value.simpleStoredMutable.a)
expectEqual(false, value.simpleStoredMutable.b)
expectEqual(0, value.simpleStoredMutable.c)

value.storedWithObservers = BagOfVariables()
expectEqual(0, value.storedWithObservers.a)
expectEqual(false, value.storedWithObservers.b)
expectEqual(0, value.storedWithObservers.c)
}

testFixedLayoutGetting()
testFixedLayoutSetting()
runAllTests()
3 changes: 3 additions & 0 deletions test/ParseableInterface/stored-properties.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ public struct HasStoredProperties {
// COMMON: @_fixed_layout public struct BagOfVariables {
@_fixed_layout
public struct BagOfVariables {
// COMMON: private let hidden: [[INT]] = 0
private let hidden: Int = 0

// COMMON: public let a: [[INT]] = 0
public let a: Int = 0

Expand Down