Skip to content

Commit

Permalink
[cxx-interop][stdlib] windows - use new hash inline functions like ot…
Browse files Browse the repository at this point in the history
…her platforms

The PR #77857 added windows-specific workaround for #77856, that happened after #77843. Unfortunately this caused a new issue on windows - #78119. It looks like windows is suffering from a similar serialization issue as libstdc++, although its even more complex as the callAsFunction is not only a derived function from a base class, the base class although has a static call operator. In any case, the libstdc++ callAsFunction deserialization fix should align with the static operator () deserialization too, so for now make windows use the same workaround as other platforms to avoid the deserialization crash (77856).

This change was tested on i686 windows too, ensuring that IR verifier crash no longer happens
  • Loading branch information
hyp committed Dec 13, 2024
1 parent e6db7fa commit ea08b2d
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 15 deletions.
6 changes: 3 additions & 3 deletions stdlib/public/Cxx/cxxshim/libcxxstdlibshim.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,19 @@

/// Used for std::string conformance to Swift.Hashable
typedef std::hash<std::string> __swift_interopHashOfString;
inline std::size_t __swift_interopComputeHashOfString(std::string str) {
inline std::size_t __swift_interopComputeHashOfString(const std::string &str) {
return __swift_interopHashOfString()(str);
}

/// Used for std::u16string conformance to Swift.Hashable
typedef std::hash<std::u16string> __swift_interopHashOfU16String;
inline std::size_t __swift_interopComputeHashOfU16String(std::u16string str) {
inline std::size_t __swift_interopComputeHashOfU16String(const std::u16string &str) {
return __swift_interopHashOfU16String()(str);
}

/// Used for std::u32string conformance to Swift.Hashable
typedef std::hash<std::u32string> __swift_interopHashOfU32String;
inline std::size_t __swift_interopComputeHashOfU32String(std::u32string str) {
inline std::size_t __swift_interopComputeHashOfU32String(const std::u32string &str) {
return __swift_interopHashOfU32String()(str);
}

Expand Down
12 changes: 0 additions & 12 deletions stdlib/public/Cxx/std/String.swift
Original file line number Diff line number Diff line change
Expand Up @@ -198,11 +198,7 @@ extension std.string: Hashable {
@_alwaysEmitIntoClient
public func hash(into hasher: inout Hasher) {
// Call std::hash<std::string>::operator()
#if os(Windows) // FIXME: https://github.com/swiftlang/swift/issues/77856
let cxxHash = __swift_interopHashOfString().callAsFunction(self)
#else
let cxxHash = __swift_interopComputeHashOfString(self)
#endif
hasher.combine(cxxHash)
}
}
Expand All @@ -211,11 +207,7 @@ extension std.u16string: Hashable {
@_alwaysEmitIntoClient
public func hash(into hasher: inout Hasher) {
// Call std::hash<std::u16string>::operator()
#if os(Windows) // FIXME: https://github.com/swiftlang/swift/issues/77856
let cxxHash = __swift_interopHashOfU16String().callAsFunction(self)
#else
let cxxHash = __swift_interopComputeHashOfU16String(self)
#endif
hasher.combine(cxxHash)
}
}
Expand All @@ -224,11 +216,7 @@ extension std.u32string: Hashable {
@_alwaysEmitIntoClient
public func hash(into hasher: inout Hasher) {
// Call std::hash<std::u32string>::operator()
#if os(Windows) // FIXME: https://github.com/swiftlang/swift/issues/77856
let cxxHash = __swift_interopHashOfU32String().callAsFunction(self)
#else
let cxxHash = __swift_interopComputeHashOfU32String(self)
#endif
hasher.combine(cxxHash)
}
}
Expand Down
6 changes: 6 additions & 0 deletions test/Interop/Cxx/stdlib/Inputs/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ module StdString {
export *
}

module StdStringAndVector {
header "std-string-and-vector.h"
requires cplusplus
export *
}

module StdStringView {
header "std-string-view.h"
requires cplusplus
Expand Down
11 changes: 11 additions & 0 deletions test/Interop/Cxx/stdlib/Inputs/std-string-and-vector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include <string>
#include <vector>

struct Item {
std::vector<std::string> keys;
std::vector<std::string> values;
};

inline Item get_item() {
return {};
}
20 changes: 20 additions & 0 deletions test/Interop/Cxx/stdlib/use-std-string-with-opts.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// RUN: %target-run-simple-swift(-I %S/Inputs -cxx-interoperability-mode=default -Xcc -std=c++20 -O)
//
// REQUIRES: executable_test

// Tests optimizations related to CxxStdlib.

import StdlibUnittest
import CxxStdlib
import StdStringAndVector

var StdStringOptTestSuite = TestSuite("StdStringWithOpts")

StdStringOptTestSuite.test("std::string with Hashable conformance optimized") {
let item = get_item()
let dict = Dictionary(uniqueKeysWithValues: zip(item.keys, item.values).lazy)

expectEqual(dict.count, 0)
}

runAllTests()

0 comments on commit ea08b2d

Please sign in to comment.