Skip to content

Commit dc3978f

Browse files
authored
Merge pull request #61853 from apple/egorzhdan/cxx-rac-iterator-nullptr
[cxx-interop] Fix nullptr casts in auto-conformance logic
2 parents 18785b8 + 3e29920 commit dc3978f

File tree

2 files changed

+92
-2
lines changed

2 files changed

+92
-2
lines changed

lib/ClangImporter/ClangDerivedConformances.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -273,13 +273,13 @@ void swift::conformToCxxIteratorIfNeeded(
273273

274274
// Try to conform to UnsafeCxxRandomAccessIterator if possible.
275275

276-
auto minus = dyn_cast<FuncDecl>(getMinusOperator(decl));
276+
auto minus = dyn_cast_or_null<FuncDecl>(getMinusOperator(decl));
277277
if (!minus)
278278
return;
279279
auto distanceTy = minus->getResultInterfaceType();
280280
// distanceTy conforms to BinaryInteger, this is ensured by getMinusOperator.
281281

282-
auto plusEqual = dyn_cast<FuncDecl>(getPlusEqualOperator(decl, distanceTy));
282+
auto plusEqual = dyn_cast_or_null<FuncDecl>(getPlusEqualOperator(decl, distanceTy));
283283
if (!plusEqual)
284284
return;
285285

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

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,4 +373,94 @@ struct HasNoDereferenceOperator {
373373
}
374374
};
375375

376+
// MARK: Types that claim to be random access iterators, but actually aren't.
377+
378+
struct HasNoMinusOperator {
379+
int value;
380+
381+
using iterator_category = std::random_access_iterator_tag;
382+
using value_type = int;
383+
using pointer = int *;
384+
using reference = const int &;
385+
using difference_type = int;
386+
387+
HasNoMinusOperator(int value) : value(value) {}
388+
HasNoMinusOperator(const HasNoMinusOperator &other) = default;
389+
390+
const int &operator*() const { return value; }
391+
392+
HasNoMinusOperator &operator++() {
393+
value++;
394+
return *this;
395+
}
396+
void operator+=(difference_type v) { value += v; }
397+
void operator-=(difference_type v) { value -= v; }
398+
HasNoMinusOperator operator+(difference_type v) const {
399+
return HasNoMinusOperator(value + v);
400+
}
401+
HasNoMinusOperator operator-(difference_type v) const {
402+
return HasNoMinusOperator(value - v);
403+
}
404+
friend HasNoMinusOperator operator+(difference_type v,
405+
const HasNoMinusOperator &it) {
406+
return it + v;
407+
}
408+
409+
bool operator<(const HasNoMinusOperator &other) const {
410+
return value < other.value;
411+
}
412+
413+
bool operator==(const HasNoMinusOperator &other) const {
414+
return value == other.value;
415+
}
416+
bool operator!=(const HasNoMinusOperator &other) const {
417+
return value != other.value;
418+
}
419+
};
420+
421+
struct HasNoPlusEqualOperator {
422+
int value;
423+
424+
using iterator_category = std::random_access_iterator_tag;
425+
using value_type = int;
426+
using pointer = int *;
427+
using reference = const int &;
428+
using difference_type = int;
429+
430+
HasNoPlusEqualOperator(int value) : value(value) {}
431+
HasNoPlusEqualOperator(const HasNoPlusEqualOperator &other) = default;
432+
433+
const int &operator*() const { return value; }
434+
435+
HasNoPlusEqualOperator &operator++() {
436+
value++;
437+
return *this;
438+
}
439+
void operator-=(difference_type v) { value -= v; }
440+
HasNoPlusEqualOperator operator+(difference_type v) const {
441+
return HasNoPlusEqualOperator(value + v);
442+
}
443+
HasNoPlusEqualOperator operator-(difference_type v) const {
444+
return HasNoPlusEqualOperator(value - v);
445+
}
446+
friend HasNoPlusEqualOperator operator+(difference_type v,
447+
const HasNoPlusEqualOperator &it) {
448+
return it + v;
449+
}
450+
int operator-(const HasNoPlusEqualOperator &other) const {
451+
return value - other.value;
452+
}
453+
454+
bool operator<(const HasNoPlusEqualOperator &other) const {
455+
return value < other.value;
456+
}
457+
458+
bool operator==(const HasNoPlusEqualOperator &other) const {
459+
return value == other.value;
460+
}
461+
bool operator!=(const HasNoPlusEqualOperator &other) const {
462+
return value != other.value;
463+
}
464+
};
465+
376466
#endif // TEST_INTEROP_CXX_STDLIB_INPUTS_CUSTOM_ITERATOR_H

0 commit comments

Comments
 (0)