Skip to content
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
7 changes: 7 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -1798,9 +1798,16 @@ ERROR(mutating_invalid_classes,none, "%0 is not valid on %kindonly1s in "
ERROR(functions_mutating_and_not,none,
"method must not be declared both %0 and %1",
(SelfAccessKind, SelfAccessKind))

ERROR(static_functions_not_mutating,none,
"static functions must not be declared mutating", ())

ERROR(consuming_invalid_borrow_mutate_accessor, none,
"%0 cannot be declared consuming", (StringRef))

ERROR(ownership_modifier_unsupported_borrow_mutate_accessor, none,
"%0 ownership modifier is not yet supported on %1", (StringRef, StringRef))

ERROR(readwriter_mutatingness_differs_from_reader_or_writer_mutatingness,none,
"%0 cannot be %1 when "
"%select{both the %3 is %4 and the %5 is not %6|either the %3 is not %4 or the %5 is %6|the %3 is not %4|the %5 is %6}2",
Expand Down
15 changes: 7 additions & 8 deletions lib/AST/Decl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3264,6 +3264,10 @@ static AccessStrategy getOpaqueReadAccessStrategy(
return AccessStrategy::getAccessor(AccessorKind::Read2, dispatch);
if (storage->requiresOpaqueReadCoroutine())
return AccessStrategy::getAccessor(AccessorKind::Read, dispatch);

if (storage->getParsedAccessor(AccessorKind::Borrow)) {
return AccessStrategy::getAccessor(AccessorKind::Borrow, dispatch);
}
return AccessStrategy::getAccessor(AccessorKind::Get, dispatch);
}

Expand Down Expand Up @@ -3435,11 +3439,6 @@ bool AbstractStorageDecl::requiresOpaqueSetter() const {
if (!supportsMutation()) {
return false;
}

// If a mutate accessor is present, we don't need a setter.
if (getAccessor(AccessorKind::Mutate)) {
return false;
}
return true;
}

Expand All @@ -3450,7 +3449,7 @@ bool AbstractStorageDecl::requiresOpaqueReadCoroutine() const {
AccessorKind::Read2);

// If a borrow accessor is present, we don't need a read coroutine.
if (getAccessor(AccessorKind::Borrow)) {
if (getParsedAccessor(AccessorKind::Borrow)) {
return false;
}
return getOpaqueReadOwnership() != OpaqueReadOwnership::Owned;
Expand All @@ -3462,7 +3461,7 @@ bool AbstractStorageDecl::requiresOpaqueRead2Coroutine() const {
return false;

// If a borrow accessor is present, we don't need a read coroutine.
if (getAccessor(AccessorKind::Borrow)) {
if (getParsedAccessor(AccessorKind::Borrow)) {
return false;
}
return getOpaqueReadOwnership() != OpaqueReadOwnership::Owned;
Expand Down Expand Up @@ -7595,7 +7594,7 @@ StringRef swift::getAccessorNameForDiagnostic(AccessorKind accessorKind,
case AccessorKind::Init:
return article ? "an init accessor" : "init accessor";
case AccessorKind::Borrow:
return article ? " a 'borrow' accessor" : "borrow accessor";
return article ? "a 'borrow' accessor" : "borrow accessor";
case AccessorKind::Mutate:
return article ? "a 'mutate' accessor" : "mutate accessor";
}
Expand Down
25 changes: 25 additions & 0 deletions lib/Sema/TypeCheckAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -708,6 +708,31 @@ void AttributeChecker::visitMutationAttr(DeclAttribute *attr) {
// Verify that we don't have a static function.
if (FD->isStatic())
diagnoseAndRemoveAttr(attr, diag::static_functions_not_mutating);

auto *accessor = dyn_cast<AccessorDecl>(FD);
if (accessor &&
(accessor->isBorrowAccessor() || accessor->isMutateAccessor())) {
if (attrModifier == SelfAccessKind::Consuming ||
attrModifier == SelfAccessKind::LegacyConsuming) {
diagnoseAndRemoveAttr(
attr, diag::consuming_invalid_borrow_mutate_accessor,
getAccessorNameForDiagnostic(accessor, /*article*/ true));
}
if (attrModifier == SelfAccessKind::NonMutating &&
accessor->isMutateAccessor()) {
diagnoseAndRemoveAttr(
attr, diag::ownership_modifier_unsupported_borrow_mutate_accessor,
attr->getAttrName(),
getAccessorNameForDiagnostic(accessor, /*article*/ true));
}
if (attrModifier == SelfAccessKind::Mutating &&
accessor->isBorrowAccessor()) {
diagnoseAndRemoveAttr(
attr, diag::ownership_modifier_unsupported_borrow_mutate_accessor,
attr->getAttrName(),
getAccessorNameForDiagnostic(accessor, /*article*/ true));
}
}
}

void AttributeChecker::visitDynamicAttr(DynamicAttr *attr) {
Expand Down
25 changes: 13 additions & 12 deletions lib/Sema/TypeCheckStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1875,6 +1875,13 @@ synthesizeModify2CoroutineSetterBody(AccessorDecl *setter, ASTContext &ctx) {
setter, TargetImpl::Implementation, setter->getStorage(), ctx);
}

static std::pair<BraceStmt *, bool>
synthesizeMutateSetterBody(AccessorDecl *setter, ASTContext &ctx) {
// This should call the mutate accessor.
return synthesizeTrivialSetterBodyWithStorage(
setter, TargetImpl::Implementation, setter->getStorage(), ctx);
}

static Expr *maybeWrapInOutExpr(Expr *expr, ASTContext &ctx) {
if (auto lvalueType = expr->getType()->getAs<LValueType>()) {
auto type = lvalueType->getObjectType();
Expand Down Expand Up @@ -2071,7 +2078,7 @@ synthesizeSetterBody(AccessorDecl *setter, ASTContext &ctx) {
return synthesizeModify2CoroutineSetterBody(setter, ctx);

case WriteImplKind::Mutate:
llvm_unreachable("synthesizing setter from mutate");
return synthesizeMutateSetterBody(setter, ctx);
}
llvm_unreachable("bad WriteImplKind");
}
Expand Down Expand Up @@ -2476,7 +2483,9 @@ static AccessorDecl *createSetterPrototype(AbstractStorageDecl *storage,
}
break;
case WriteImplKind::Mutate:
llvm_unreachable("mutate accessor is not yet implemented");
if (auto mutate = storage->getOpaqueAccessor(AccessorKind::Mutate)) {
asAvailableAs.push_back(mutate);
}
}

if (!asAvailableAs.empty()) {
Expand Down Expand Up @@ -2804,11 +2813,6 @@ bool RequiresOpaqueModifyCoroutineRequest::evaluate(
if (protoDecl->isObjC())
return false;

// If a mutate accessor is present, we don't need a modify coroutine
if (storage->getAccessor(AccessorKind::Mutate)) {
return false;
}

return true;
}

Expand Down Expand Up @@ -2937,9 +2941,8 @@ IsAccessorTransparentRequest::evaluate(Evaluator &evaluator,
case WriteImplKind::MutableAddress:
case WriteImplKind::Modify:
case WriteImplKind::Modify2:
break;
case WriteImplKind::Mutate:
llvm_unreachable("mutate accessor is not yet implemented");
break;
}
break;

Expand All @@ -2950,14 +2953,12 @@ IsAccessorTransparentRequest::evaluate(Evaluator &evaluator,
case AccessorKind::Init:
break;
case AccessorKind::Borrow:
llvm_unreachable("borrow accessor is not yet implemented");
case AccessorKind::WillSet:
case AccessorKind::DidSet:
case AccessorKind::Address:
case AccessorKind::MutableAddress:
llvm_unreachable("bad synthesized function kind");
case AccessorKind::Mutate:
llvm_unreachable("mutate accessor is not yet implemented");
llvm_unreachable("bad synthesized function kind");
}

switch (storage->getReadWriteImpl()) {
Expand Down
65 changes: 33 additions & 32 deletions test/IRGen/borrow_accessor_large.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
// RUN: %target-swift-frontend -c %s -Xllvm -sil-print-after=loadable-address -enable-experimental-feature BorrowAndMutateAccessors 2>&1 | %FileCheck %s
// RUN: %target-swift-frontend -emit-irgen %s -enable-experimental-feature BorrowAndMutateAccessors 2>&1 | %FileCheck --check-prefixes=CHECK-IRGEN %s

// REQUIRES: swift_feature_BorrowAndMutateAccessors
// REQUIRES: OS=macosx
Expand Down Expand Up @@ -137,9 +138,9 @@ func nctest() {
// CHECK: }

// IRGen result type is PtrTy because we are returning a class reference
// CHECK-IRGEN: define hidden swiftcc ptr @"$s21borrow_accessor_large11LargeStructV0A5KlassAA0F0Cvb"(ptr noalias nocapture swiftself dereferenceable(208) [[REG0]]) {{.*}} {
// CHECK-IRGEN: define hidden swiftcc ptr @"$s21borrow_accessor_large11LargeStructV0A5KlassAA0F0Cvb"(ptr noalias swiftself captures(none) dereferenceable(208) [[REG0:%.*]]) {{.*}} {
// CHECK-IRGEN: entry:
// CHECK-IRGEN: %._k = getelementptr inbounds %T21borrow_accessor_large11LargeStructV, ptr [[REG0]], i32 0, i32 0
// CHECK-IRGEN: %._k = getelementptr inbounds nuw %T21borrow_accessor_large11LargeStructV, ptr [[REG0]], i32 0, i32 0
// CHECK-IRGEN: [[REG1:%.*]] = load ptr, ptr %._k, align 8
// CHECK-IRGEN: ret ptr [[REG1]]
// CHECK-IRGEN: }
Expand All @@ -151,11 +152,11 @@ func nctest() {
// CHECK: return [[REG3]]
// CHECK: }

// CHECK-IRGEN: define hidden swiftcc i64 @"$s21borrow_accessor_large11LargeStructV0a5SmallE0AA0fE0Vvb"(ptr noalias nocapture swiftself dereferenceable(208) [[REG0]]) {{.*}} {
// CHECK-IRGEN: define hidden swiftcc i64 @"$s21borrow_accessor_large11LargeStructV0a5SmallE0AA0fE0Vvb"(ptr noalias swiftself captures(none) dereferenceable(208) [[REG0:%.*]]) {{.*}} {
// CHECK-IRGEN: entry:
// CHECK-IRGEN: %._smallStruct = getelementptr inbounds %T21borrow_accessor_large11LargeStructV, ptr [[REG0]], i32 0, i32 4
// CHECK-IRGEN: %._smallStruct.id = getelementptr inbounds %T21borrow_accessor_large11SmallStructV, ptr %._smallStruct, i32 0, i32 0
// CHECK-IRGEN: %._smallStruct.id._value = getelementptr inbounds %TSi, ptr %._smallStruct.id, i32 0, i32 0
// CHECK-IRGEN: %._smallStruct = getelementptr inbounds nuw %T21borrow_accessor_large11LargeStructV, ptr [[REG0]], i32 0, i32 4
// CHECK-IRGEN: %._smallStruct.id = getelementptr inbounds nuw %T21borrow_accessor_large11SmallStructV, ptr %._smallStruct, i32 0, i32 0
// CHECK-IRGEN: %._smallStruct.id._value = getelementptr inbounds nuw %TSi, ptr %._smallStruct.id, i32 0, i32 0
// CHECK-IRGEN: [[REG1:%.*]] = load i64, ptr %._smallStruct.id._value, align 8
// CHECK-IRGEN: ret i64 [[REG1]]
// CHECK-IRGEN: }
Expand All @@ -169,9 +170,9 @@ func nctest() {
// CHECK: return [[REG5]]
// CHECK: }

// CHECK-IRGEN: define hidden swiftcc void @"$s21borrow_accessor_large11LargeStructV0C10PropBorrowAA0dF0Vvb"(ptr noalias nocapture sret(%T21borrow_accessor_large9LargePropV) [[REG0]], ptr noalias nocapture swiftself dereferenceable(208) [[REG1]]) {{.*}} {
// CHECK-IRGEN: define hidden swiftcc void @"$s21borrow_accessor_large11LargeStructV0C10PropBorrowAA0dF0Vvb"(ptr noalias sret(%T21borrow_accessor_large9LargePropV) captures(none) [[REG0:%.*]], ptr noalias swiftself captures(none) dereferenceable(208) [[REG1:%.*]]) {{.*}} {
// CHECK-IRGEN: entry:
// CHECK-IRGEN: %._largeProp = getelementptr inbounds %T21borrow_accessor_large11LargeStructV, ptr [[REG1]], i32 0, i32 3
// CHECK-IRGEN: %._largeProp = getelementptr inbounds nuw %T21borrow_accessor_large11LargeStructV, ptr [[REG1]], i32 0, i32 3
// CHECK-IRGEN: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[REG0]], ptr align 8 %._largeProp, i64 64, i1 false)
// CHECK-IRGEN: ret void
// CHECK-IRGEN: }
Expand All @@ -184,40 +185,40 @@ func nctest() {
// CHECK: return [[REG3]]
// CHECK: }

// CHECK-IRGEN: define hidden swiftcc void @"$s21borrow_accessor_large11LargeStructV0C11TupleBorrowAA5KlassC_A7Ftvb"(ptr noalias nocapture sret(<{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>) [[REG0]], ptr noalias nocapture swiftself dereferenceable(208) [[REG1]]) {{.*}} {
// CHECK-IRGEN: define hidden swiftcc void @"$s21borrow_accessor_large11LargeStructV0C11TupleBorrowAA5KlassC_A7Ftvb"(ptr noalias sret(<{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>) captures(none) [[REG0:%.*]], ptr noalias swiftself captures(none) dereferenceable(208) [[REG1:%.*]]) {{.*}} {
// CHECK-IRGEN: entry:
// CHECK-IRGEN: %._largeTuple = getelementptr inbounds %T21borrow_accessor_large11LargeStructV, ptr [[REG1]], i32 0, i32 2
// CHECK-IRGEN: %._largeTuple.elt = getelementptr inbounds <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr %._largeTuple, i32 0, i32 0
// CHECK-IRGEN: %._largeTuple = getelementptr inbounds nuw %T21borrow_accessor_large11LargeStructV, ptr [[REG1]], i32 0, i32 2
// CHECK-IRGEN: %._largeTuple.elt = getelementptr inbounds nuw <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr %._largeTuple, i32 0, i32 0
// CHECK-IRGEN: [[REG2:%.*]] = load ptr, ptr %._largeTuple.elt, align 8
// CHECK-IRGEN: %._largeTuple.elt1 = getelementptr inbounds <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr %._largeTuple, i32 0, i32 1
// CHECK-IRGEN: %._largeTuple.elt1 = getelementptr inbounds nuw <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr %._largeTuple, i32 0, i32 1
// CHECK-IRGEN: [[REG3:%.*]] = load ptr, ptr %._largeTuple.elt1, align 8
// CHECK-IRGEN: %._largeTuple.elt2 = getelementptr inbounds <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr %._largeTuple, i32 0, i32 2
// CHECK-IRGEN: %._largeTuple.elt2 = getelementptr inbounds nuw <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr %._largeTuple, i32 0, i32 2
// CHECK-IRGEN: [[REG4:%.*]] = load ptr, ptr %._largeTuple.elt2, align 8
// CHECK-IRGEN: %._largeTuple.elt3 = getelementptr inbounds <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr %._largeTuple, i32 0, i32 3
// CHECK-IRGEN: %._largeTuple.elt3 = getelementptr inbounds nuw <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr %._largeTuple, i32 0, i32 3
// CHECK-IRGEN: [[REG5:%.*]] = load ptr, ptr %._largeTuple.elt3, align 8
// CHECK-IRGEN: %._largeTuple.elt4 = getelementptr inbounds <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr %._largeTuple, i32 0, i32 4
// CHECK-IRGEN: %._largeTuple.elt4 = getelementptr inbounds nuw <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr %._largeTuple, i32 0, i32 4
// CHECK-IRGEN: [[REG6:%.*]] = load ptr, ptr %._largeTuple.elt4, align 8
// CHECK-IRGEN: %._largeTuple.elt5 = getelementptr inbounds <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr %._largeTuple, i32 0, i32 5
// CHECK-IRGEN: %._largeTuple.elt5 = getelementptr inbounds nuw <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr %._largeTuple, i32 0, i32 5
// CHECK-IRGEN: [[REG7:%.*]] = load ptr, ptr %._largeTuple.elt5, align 8
// CHECK-IRGEN: %._largeTuple.elt6 = getelementptr inbounds <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr %._largeTuple, i32 0, i32 6
// CHECK-IRGEN: %._largeTuple.elt6 = getelementptr inbounds nuw <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr %._largeTuple, i32 0, i32 6
// CHECK-IRGEN: [[REG8:%.*]] = load ptr, ptr %._largeTuple.elt6, align 8
// CHECK-IRGEN: %._largeTuple.elt7 = getelementptr inbounds <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr %._largeTuple, i32 0, i32 7
// CHECK-IRGEN: %._largeTuple.elt7 = getelementptr inbounds nuw <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr %._largeTuple, i32 0, i32 7
// CHECK-IRGEN: [[REG9:%.*]] = load ptr, ptr %._largeTuple.elt7, align 8
// CHECK-IRGEN: %.elt = getelementptr inbounds <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr [[REG0]], i32 0, i32 0
// CHECK-IRGEN: %.elt = getelementptr inbounds nuw <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr [[REG0]], i32 0, i32 0
// CHECK-IRGEN: store ptr [[REG2]], ptr %.elt, align 8
// CHECK-IRGEN: %.elt8 = getelementptr inbounds <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr [[REG0]], i32 0, i32 1
// CHECK-IRGEN: %.elt8 = getelementptr inbounds nuw <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr [[REG0]], i32 0, i32 1
// CHECK-IRGEN: store ptr [[REG3]], ptr %.elt8, align 8
// CHECK-IRGEN: %.elt9 = getelementptr inbounds <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr [[REG0]], i32 0, i32 2
// CHECK-IRGEN: %.elt9 = getelementptr inbounds nuw <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr [[REG0]], i32 0, i32 2
// CHECK-IRGEN: store ptr [[REG4]], ptr %.elt9, align 8
// CHECK-IRGEN: %.elt10 = getelementptr inbounds <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr [[REG0]], i32 0, i32 3
// CHECK-IRGEN: %.elt10 = getelementptr inbounds nuw <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr [[REG0]], i32 0, i32 3
// CHECK-IRGEN: store ptr [[REG5]], ptr %.elt10, align 8
// CHECK-IRGEN: %.elt11 = getelementptr inbounds <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr [[REG0]], i32 0, i32 4
// CHECK-IRGEN: %.elt11 = getelementptr inbounds nuw <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr [[REG0]], i32 0, i32 4
// CHECK-IRGEN: store ptr [[REG6]], ptr %.elt11, align 8
// CHECK-IRGEN: %.elt12 = getelementptr inbounds <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr [[REG0]], i32 0, i32 5
// CHECK-IRGEN: %.elt12 = getelementptr inbounds nuw <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr [[REG0]], i32 0, i32 5
// CHECK-IRGEN: store ptr [[REG7]], ptr %.elt12, align 8
// CHECK-IRGEN: %.elt13 = getelementptr inbounds <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr [[REG0]], i32 0, i32 6
// CHECK-IRGEN: %.elt13 = getelementptr inbounds nuw <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr [[REG0]], i32 0, i32 6
// CHECK-IRGEN: store ptr [[REG8]], ptr %.elt13, align 8
// CHECK-IRGEN: %.elt14 = getelementptr inbounds <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr [[REG0]], i32 0, i32 7
// CHECK-IRGEN: %.elt14 = getelementptr inbounds nuw <{ ptr, ptr, ptr, ptr, ptr, ptr, ptr, ptr }>, ptr [[REG0]], i32 0, i32 7
// CHECK-IRGEN: store ptr [[REG9]], ptr %.elt14, align 8
// CHECK-IRGEN: ret void
// CHECK-IRGEN: }
Expand All @@ -229,11 +230,11 @@ func nctest() {
// CHECK: return [[REG3]]
// CHECK: }

// CHECK-IRGEN: define hidden swiftcc i64 @"$s21borrow_accessor_large13NCLargeStructV0A2NCAA0F0Vvb"(ptr noalias nocapture swiftself dereferenceable(72) [[REG0]]) {{.*}} {
// CHECK-IRGEN: define hidden swiftcc i64 @"$s21borrow_accessor_large13NCLargeStructV0A2NCAA0F0Vvb"(ptr noalias swiftself captures(none) dereferenceable(72) [[REG0:%.*]]) {{.*}} {
// CHECK-IRGEN: entry:
// CHECK-IRGEN: %._k = getelementptr inbounds %T21borrow_accessor_large13NCLargeStructV, ptr [[REG0]], i32 0, i32 0
// CHECK-IRGEN: %._k.id = getelementptr inbounds %T21borrow_accessor_large2NCV, ptr %._k, i32 0, i32 0
// CHECK-IRGEN: %._k.id._value = getelementptr inbounds %TSi, ptr %._k.id, i32 0, i32 0
// CHECK-IRGEN: %._k = getelementptr inbounds nuw %T21borrow_accessor_large13NCLargeStructV, ptr [[REG0]], i32 0, i32 0
// CHECK-IRGEN: %._k.id = getelementptr inbounds nuw %T21borrow_accessor_large2NCV, ptr %._k, i32 0, i32 0
// CHECK-IRGEN: %._k.id._value = getelementptr inbounds nuw %TSi, ptr %._k.id, i32 0, i32 0
// CHECK-IRGEN: [[REG1:%.*]] = load i64, ptr %._k.id._value, align 8
// CHECK-IRGEN: ret i64 [[REG1]]
// CHECK-IRGEN: }
Expand All @@ -247,9 +248,9 @@ func nctest() {
// CHECK: return [[REG5]]
// CHECK: }

// CHECK-IRGEN: define hidden swiftcc void @"$s21borrow_accessor_large13NCLargeStructV0C10PropBorrowAA11LargeNCPropVvb"(ptr noalias nocapture sret(%T21borrow_accessor_large11LargeNCPropV) [[REG0]], ptr noalias nocapture swiftself dereferenceable(72) [[REG1]]) {{.*}} {
// CHECK-IRGEN: define hidden swiftcc void @"$s21borrow_accessor_large13NCLargeStructV0C10PropBorrowAA11LargeNCPropVvb"(ptr noalias sret(%T21borrow_accessor_large11LargeNCPropV) captures(none) [[REG0]], ptr noalias swiftself captures(none) dereferenceable(72) [[REG1:%.*]]) {{.*}} {
// CHECK-IRGEN: entry:
// CHECK-IRGEN: %._largeProp = getelementptr inbounds %T21borrow_accessor_large13NCLargeStructV, ptr [[REG1]], i32 0, i32 1
// CHECK-IRGEN: %._largeProp = getelementptr inbounds nuw %T21borrow_accessor_large13NCLargeStructV, ptr [[REG1]], i32 0, i32 1
// CHECK-IRGEN: call void @llvm.memcpy.p0.p0.i64(ptr align 8 [[REG0]], ptr align 8 %._largeProp, i64 64, i1 false)
// CHECK-IRGEN: ret void
// CHECK-IRGEN: }
Expand Down
6 changes: 3 additions & 3 deletions test/Parse/borrow_and_mutate_accessors.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,23 @@ struct Wrapper {
}
}
var k2: Klass {
borrow { // expected-error{{variable cannot provide both a 'borrow' accessor and a getter}}
borrow { // expected-error{{variable cannot provide both a 'borrow' accessor and a getter}}
return _k
}
get { // expected-note{{getter defined here}}
return _k
}
}
var k3: Klass {
borrow { // expected-error{{variable cannot provide both a 'borrow' accessor and a '_read' accessor}}
borrow { // expected-error{{variable cannot provide both a 'borrow' accessor and a '_read' accessor}}
return _k
}
_read { // expected-note{{'_read' accessor defined here}}
yield _k
}
}
var k4: Klass {
borrow { // expected-error{{variable cannot provide both a 'borrow' accessor and a 'read' accessor}}
borrow { // expected-error{{variable cannot provide both a 'borrow' accessor and a 'read' accessor}}
return _k
}
read { // expected-note{{'read' accessor defined here}}
Expand Down
Loading