From 88508bf7533183f467aa1f1a84e78fd64c92eb4a Mon Sep 17 00:00:00 2001 From: Tom J Nowell Date: Mon, 29 Jun 2026 14:47:34 +0100 Subject: [PATCH 1/2] FileSystem/Archives: fix narrowing and aggregate-init portability (AppleClang/libc++) The archive readers build their entry vectors with emplace_back() of an aggregate struct, which relies on parenthesised aggregate initialisation (P0960R3). AppleClang 15 / libc++ does not fully implement it, so the emplace_back calls fail to compile. Switch to push_back() with brace-initialisation, which works on every compiler. Brace-init is stricter about narrowing, so add explicit casts to the declared member types (UInt32/UInt64/uLong -> int/uint32_t). The stored values are unchanged: the previous paren-init converted to the same member types implicitly. push_back() returns void rather than a reference, so use fileEntries.back() instead of capturing the result. No behavioural change on platforms that already compiled. Files: DirArchive.cpp, SevenZipArchive.cpp, ZipArchive.cpp Ports the code fixes from ExaDev/RecoilEngine commits 0095a7e5c5, bba6321b05 and bc0457cf7b (CI/runner changes deliberately excluded). --- rts/System/FileSystem/Archives/DirArchive.cpp | 2 +- rts/System/FileSystem/Archives/SevenZipArchive.cpp | 10 +++++----- rts/System/FileSystem/Archives/ZipArchive.cpp | 10 +++++----- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/rts/System/FileSystem/Archives/DirArchive.cpp b/rts/System/FileSystem/Archives/DirArchive.cpp index 829a56c4251..184cbbb28eb 100644 --- a/rts/System/FileSystem/Archives/DirArchive.cpp +++ b/rts/System/FileSystem/Archives/DirArchive.cpp @@ -42,7 +42,7 @@ CDirArchive::CDirArchive(const std::string& archiveName) // all variables here will use forward slashes, no need for conversion std::string rawFileName = dataDirsAccess.LocateFile(dirName + origName); - files.emplace_back(origName, std::move(rawFileName), -1, 0); + files.push_back(Files{origName, std::move(rawFileName), -1, 0}); // convert to lowercase and store lcNameIndex[StringToLower(std::move(origName))] = static_cast(files.size() - 1); diff --git a/rts/System/FileSystem/Archives/SevenZipArchive.cpp b/rts/System/FileSystem/Archives/SevenZipArchive.cpp index e40ce9e798d..a239a5d27f6 100644 --- a/rts/System/FileSystem/Archives/SevenZipArchive.cpp +++ b/rts/System/FileSystem/Archives/SevenZipArchive.cpp @@ -147,14 +147,14 @@ CSevenZipArchive::CSevenZipArchive(const std::string& name) continue; } - const auto& fd = fileEntries.emplace_back( - i, //fp - SzArEx_GetFileSize(&db, i), // size + fileEntries.push_back(FileEntry{ + static_cast(i), //fp + static_cast(SzArEx_GetFileSize(&db, i)), // size db.MTime.Vals ? static_cast(CTimeUtil::NTFSTimeToTime64(db.MTime.Vals[i].Low, db.MTime.Vals[i].High)) : 0, // modtime std::move(fileName.value()) // origName - ); + }); - lcNameIndex.emplace(StringToLower(fd.origName), fileEntries.size() - 1); + lcNameIndex.emplace(StringToLower(fileEntries.back().origName), fileEntries.size() - 1); } // for truly solid archive, one call to SzArEx_Extract() extract all files in one huge buffer, diff --git a/rts/System/FileSystem/Archives/ZipArchive.cpp b/rts/System/FileSystem/Archives/ZipArchive.cpp index 37914269c49..7c2cd24ff1c 100644 --- a/rts/System/FileSystem/Archives/ZipArchive.cpp +++ b/rts/System/FileSystem/Archives/ZipArchive.cpp @@ -58,15 +58,15 @@ CZipArchive::CZipArchive(const std::string& archiveName) unz_file_pos fp{}; unzGetFilePos(zip, &fp); - const auto& fd = fileEntries.emplace_back( + fileEntries.push_back(FileEntry{ std::move(fp), //fp - info.uncompressed_size, //size + static_cast(info.uncompressed_size), //size fName, //origName - info.crc, //crc + static_cast(info.crc), //crc static_cast(CTimeUtil::DosTimeToTime64(info.dosDate)) //modTime - ); + }); - lcNameIndex.emplace(StringToLower(fd.origName), fileEntries.size() - 1); + lcNameIndex.emplace(StringToLower(fileEntries.back().origName), fileEntries.size() - 1); } zipPerThread[0] = zip; From d1022ab810551fb62e4aeeeaa49ea45120a03084 Mon Sep 17 00:00:00 2001 From: Tom J Nowell Date: Mon, 29 Jun 2026 18:25:57 +0100 Subject: [PATCH 2/2] address review: use emplace_back(T{...}) keeping the fd reference n-morales noted push_back + fileEntries.back() can collapse back into a single emplace_back. Passing a single brace-initialised FileEntry/Files object avoids the parenthesised-aggregate-init (P0960R3) path that AppleClang/libc++ rejects, while emplace_back's returned reference (C++17) restores the named fd binding and drops the extra back() lookup. Applied to the SevenZip and Zip readers, and to the Dir reader for consistency. --- rts/System/FileSystem/Archives/DirArchive.cpp | 2 +- rts/System/FileSystem/Archives/SevenZipArchive.cpp | 4 ++-- rts/System/FileSystem/Archives/ZipArchive.cpp | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rts/System/FileSystem/Archives/DirArchive.cpp b/rts/System/FileSystem/Archives/DirArchive.cpp index 184cbbb28eb..55242d39db0 100644 --- a/rts/System/FileSystem/Archives/DirArchive.cpp +++ b/rts/System/FileSystem/Archives/DirArchive.cpp @@ -42,7 +42,7 @@ CDirArchive::CDirArchive(const std::string& archiveName) // all variables here will use forward slashes, no need for conversion std::string rawFileName = dataDirsAccess.LocateFile(dirName + origName); - files.push_back(Files{origName, std::move(rawFileName), -1, 0}); + files.emplace_back(Files{origName, std::move(rawFileName), -1, 0}); // convert to lowercase and store lcNameIndex[StringToLower(std::move(origName))] = static_cast(files.size() - 1); diff --git a/rts/System/FileSystem/Archives/SevenZipArchive.cpp b/rts/System/FileSystem/Archives/SevenZipArchive.cpp index a239a5d27f6..d5994770067 100644 --- a/rts/System/FileSystem/Archives/SevenZipArchive.cpp +++ b/rts/System/FileSystem/Archives/SevenZipArchive.cpp @@ -147,14 +147,14 @@ CSevenZipArchive::CSevenZipArchive(const std::string& name) continue; } - fileEntries.push_back(FileEntry{ + const auto& fd = fileEntries.emplace_back(FileEntry{ static_cast(i), //fp static_cast(SzArEx_GetFileSize(&db, i)), // size db.MTime.Vals ? static_cast(CTimeUtil::NTFSTimeToTime64(db.MTime.Vals[i].Low, db.MTime.Vals[i].High)) : 0, // modtime std::move(fileName.value()) // origName }); - lcNameIndex.emplace(StringToLower(fileEntries.back().origName), fileEntries.size() - 1); + lcNameIndex.emplace(StringToLower(fd.origName), fileEntries.size() - 1); } // for truly solid archive, one call to SzArEx_Extract() extract all files in one huge buffer, diff --git a/rts/System/FileSystem/Archives/ZipArchive.cpp b/rts/System/FileSystem/Archives/ZipArchive.cpp index 7c2cd24ff1c..e7b13e3e790 100644 --- a/rts/System/FileSystem/Archives/ZipArchive.cpp +++ b/rts/System/FileSystem/Archives/ZipArchive.cpp @@ -58,7 +58,7 @@ CZipArchive::CZipArchive(const std::string& archiveName) unz_file_pos fp{}; unzGetFilePos(zip, &fp); - fileEntries.push_back(FileEntry{ + const auto& fd = fileEntries.emplace_back(FileEntry{ std::move(fp), //fp static_cast(info.uncompressed_size), //size fName, //origName @@ -66,7 +66,7 @@ CZipArchive::CZipArchive(const std::string& archiveName) static_cast(CTimeUtil::DosTimeToTime64(info.dosDate)) //modTime }); - lcNameIndex.emplace(StringToLower(fileEntries.back().origName), fileEntries.size() - 1); + lcNameIndex.emplace(StringToLower(fd.origName), fileEntries.size() - 1); } zipPerThread[0] = zip;