Swift: Don't use std::hash<fs::path>.

This commit is contained in:
Alexandre Boulgakov
2023-06-14 15:41:30 +01:00
parent 37a62d3021
commit afb7070fd3
6 changed files with 14 additions and 44 deletions

View File

@@ -104,7 +104,7 @@ class SwiftLocationExtractor {
private:
TrapLabel<FileTag> fetchFileLabel(const std::filesystem::path& file);
TrapDomain& trap;
std::unordered_map<std::filesystem::path, TrapLabel<FileTag>> store;
std::unordered_map<std::filesystem::path, TrapLabel<FileTag>, codeql::PathHash> store;
};
template <typename Locatable>

View File

@@ -9,26 +9,7 @@ swift_cc_library(
hdrs = glob(
["*.h"],
exclude = ["FsLogger.h"],
) + [":path_hash_workaround"],
),
visibility = ["//swift:__subpackages__"],
deps = ["//swift/logging"],
)
genrule(
name = "path_hash_workaround",
srcs = [
"PathHash.h.workaround",
"PathHash.h.fixed",
],
outs = ["PathHash.h"],
# see if https://cplusplus.github.io/LWG/issue3657 is fixed with the current compiler or not
# if fixed, PathHash.h.workaround will not compile
cmd = "\n".join([
"if clang -c -x c++ -std=c++20 -Wno-pragma-once-outside-header \\",
" $(rootpath PathHash.h.workaround) -o /dev/null &> /dev/null; then",
" cp $(rootpath PathHash.h.workaround) $@",
"else",
" cp $(rootpath PathHash.h.fixed) $@",
"fi",
]),
)

View File

@@ -0,0 +1,11 @@
#pragma once
#include <filesystem>
namespace codeql {
struct PathHash {
auto operator()(const std::filesystem::path& path) const {
return std::filesystem::hash_value(path);
}
};
} // namespace codeql

View File

@@ -1,4 +0,0 @@
#pragma once
#include <filesystem>
#include <functional>

View File

@@ -1,17 +0,0 @@
#pragma once
#include <filesystem>
#include <functional>
// workaround for https://cplusplus.github.io/LWG/issue3657
// notice that theoretically by the standard you are not allowed to specialize on std types...
// but it works, and this is recognized as a defect of the standard.
// Using a non-standard Hasher type would be a huge pain, as the automatic hash implementation of
// std::variant would not kick in (we use std::filesystem::path in a variant used as a map key).
namespace std {
template <>
struct hash<filesystem::path> {
size_t operator()(const filesystem::path& path) const { return hash_value(path); }
};
} // namespace std

View File

@@ -114,7 +114,6 @@ class FileInterceptor {
}
int open(const char* path, int flags, mode_t mode = 0) const {
fs::path fsPath{path};
CODEQL_ASSERT((flags & O_ACCMODE) == O_RDONLY, "We should only be intercepting file reads");
// try to use the hash map first
errno = 0;
@@ -162,7 +161,7 @@ class FileInterceptor {
};
std::optional<std::string> getHashOfRealFile(const fs::path& path) {
static std::unordered_map<fs::path, std::string> cache;
static std::unordered_map<fs::path, std::string, codeql::PathHash> cache;
auto resolved = resolvePath(path);
if (auto found = cache.find(resolved); found != cache.end()) {
return found->second;