Skip to content

Commit 2b2846d

Browse files
authored
Merge pull request #67549 from apple/egorzhdan/mutable-pointee-assertion
[cxx-interop] Fix assertion failure in IRGen with mutable dereference operators
2 parents 9b39805 + b860fdd commit 2b2846d

File tree

7 files changed

+77
-5
lines changed

7 files changed

+77
-5
lines changed

lib/ClangImporter/ImportName.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1921,7 +1921,11 @@ ImportedName NameImporter::importNameImpl(const clang::NamedDecl *D,
19211921
if (auto cxxMethod = dyn_cast<clang::CXXMethodDecl>(functionDecl)) {
19221922
if (op == clang::OverloadedOperatorKind::OO_Star &&
19231923
cxxMethod->param_empty()) {
1924-
if (cxxMethod->isConst())
1924+
auto returnType = functionDecl->getReturnType();
1925+
if ((!returnType->isReferenceType() &&
1926+
!returnType->isAnyPointerType()) ||
1927+
returnType->isAnyPointerType() ||
1928+
returnType->getPointeeType().isConstQualified())
19251929
result.info.accessorKind = ImportedAccessorKind::DereferenceGetter;
19261930
else
19271931
result.info.accessorKind = ImportedAccessorKind::DereferenceSetter;

lib/ClangImporter/SwiftDeclSynthesizer.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1691,7 +1691,6 @@ SwiftDeclSynthesizer::makeDereferencedPointeeProperty(FuncDecl *getter,
16911691
getterImpl->getStartLoc(), ctx.getIdentifier("pointee"), dc);
16921692
result->setInterfaceType(elementTy);
16931693
result->setAccess(AccessLevel::Public);
1694-
result->setImplInfo(StorageImplInfo::getImmutableComputed());
16951694

16961695
AccessorDecl *getterDecl = AccessorDecl::create(
16971696
ctx, getterImpl->getLoc(), getterImpl->getLoc(), AccessorKind::Get,
@@ -1709,6 +1708,9 @@ SwiftDeclSynthesizer::makeDereferencedPointeeProperty(FuncDecl *getter,
17091708
if (getterImpl->isMutating()) {
17101709
getterDecl->setSelfAccessKind(SelfAccessKind::Mutating);
17111710
result->setIsGetterMutating(true);
1711+
} else {
1712+
getterDecl->setSelfAccessKind(SelfAccessKind::NonMutating);
1713+
result->setIsGetterMutating(false);
17121714
}
17131715

17141716
AccessorDecl *setterDecl = nullptr;
@@ -1737,6 +1739,9 @@ SwiftDeclSynthesizer::makeDereferencedPointeeProperty(FuncDecl *getter,
17371739
if (setterImpl->isMutating()) {
17381740
setterDecl->setSelfAccessKind(SelfAccessKind::Mutating);
17391741
result->setIsSetterMutating(true);
1742+
} else {
1743+
setterDecl->setSelfAccessKind(SelfAccessKind::NonMutating);
1744+
result->setIsSetterMutating(false);
17401745
}
17411746
}
17421747

test/Interop/Cxx/stdlib/overlay/Inputs/custom-iterator.h

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -839,14 +839,15 @@ struct InputOutputIterator {
839839
std::output_iterator_tag {};
840840
using value_type = int;
841841
using pointer = int *;
842-
using reference = const int &;
842+
using reference = int &;
843+
using const_reference = const int &;
843844
using difference_type = int;
844845

845846
InputOutputIterator(int value) : value(value) {}
846847
InputOutputIterator(const InputOutputIterator &other) = default;
847848

848-
const int &operator*() const { return value; }
849-
int &operator*() { return value; }
849+
const_reference operator*() const { return value; }
850+
reference operator*() { return value; }
850851

851852
InputOutputIterator &operator++() {
852853
value++;
@@ -866,6 +867,41 @@ struct InputOutputIterator {
866867
}
867868
};
868869

870+
struct InputOutputConstIterator {
871+
private:
872+
int *value;
873+
874+
public:
875+
struct iterator_category : std::input_iterator_tag,
876+
std::output_iterator_tag {};
877+
using value_type = int;
878+
using pointer = int *;
879+
using reference = int &;
880+
using difference_type = int;
881+
882+
InputOutputConstIterator(int *value) : value(value) {}
883+
InputOutputConstIterator(const InputOutputConstIterator &other) = default;
884+
885+
reference operator*() const { return *value; }
886+
887+
InputOutputConstIterator &operator++() {
888+
value++;
889+
return *this;
890+
}
891+
InputOutputConstIterator operator++(int) {
892+
auto tmp = InputOutputConstIterator(value);
893+
value++;
894+
return tmp;
895+
}
896+
897+
bool operator==(const InputOutputConstIterator &other) const {
898+
return value == other.value;
899+
}
900+
bool operator!=(const InputOutputConstIterator &other) const {
901+
return value != other.value;
902+
}
903+
};
904+
869905
struct MutableRACIterator {
870906
private:
871907
int value;

test/Interop/Cxx/stdlib/overlay/Inputs/custom-sequence.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,4 +135,13 @@ struct HasInheritedTemplatedConstIterator {
135135
typedef HasInheritedTemplatedConstIterator<int>
136136
HasInheritedTemplatedConstIteratorInt;
137137

138+
struct HasInputOutputConstIterator {
139+
typedef InputOutputConstIterator iterator;
140+
141+
mutable int x[5] = {5, 4, 3, 2, 1};
142+
143+
iterator begin() const { return iterator(x); }
144+
iterator end() const { return iterator(x + 5); }
145+
};
146+
138147
#endif // TEST_INTEROP_CXX_STDLIB_INPUTS_CUSTOM_SEQUENCE_H

test/Interop/Cxx/stdlib/overlay/custom-convertible-to-collection.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,4 +71,10 @@ CxxSequenceTestSuite.test("HasInheritedTemplatedConstIterator to Swift.Array") {
7171
expectEqual([1, 2, 3, 4, 5, 6] as [Int32], array)
7272
}
7373

74+
CxxSequenceTestSuite.test("HasInputOutputConstIterator to Swift.Array") {
75+
let seq = HasInputOutputConstIterator()
76+
let array = Array(seq)
77+
expectEqual([5, 4, 3, 2, 1] as [Int32], array)
78+
}
79+
7480
runAllTests()

test/Interop/Cxx/stdlib/overlay/custom-iterator-module-interface.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,12 @@
132132
// CHECK: typealias Pointee = Int32
133133
// CHECK: }
134134

135+
// CHECK: struct InputOutputConstIterator : UnsafeCxxMutableInputIterator {
136+
// CHECK: func successor() -> InputOutputConstIterator
137+
// CHECK: var pointee: Int32 { get nonmutating set }
138+
// CHECK: typealias Pointee = Int32
139+
// CHECK: }
140+
135141
// CHECK: struct MutableRACIterator : UnsafeCxxRandomAccessIterator, UnsafeCxxMutableInputIterator {
136142
// CHECK: func successor() -> MutableRACIterator
137143
// CHECK: var pointee: Int32

test/Interop/Cxx/stdlib/overlay/custom-sequence-module-interface.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,9 @@
5656
// CHECK-NOT: typealias RawIterator
5757
// CHECK: }
5858
// CHECK: typealias HasUninstantiatableIterator = HasTemplatedIterator<Int32, NoDefinition<Int32>>
59+
60+
// CHECK: struct HasInputOutputConstIterator : CxxConvertibleToCollection {
61+
// CHECK: typealias Element = InputOutputConstIterator.Pointee
62+
// CHECK: typealias Iterator = CxxIterator<HasInputOutputConstIterator>
63+
// CHECK: typealias RawIterator = HasInputOutputConstIterator.iterator
64+
// CHECK: }

0 commit comments

Comments
 (0)