Merge pull request #3290 from ziglang/more-test-coverage

significantly increase test coverage
This commit is contained in:
Andrew Kelley 2019-09-22 21:18:27 -04:00 committed by GitHub
commit 35c1d8cefc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 566 additions and 164 deletions

1
.gitattributes vendored
View File

@ -1,4 +1,5 @@
*.zig text eol=lf
*.txt text eol=lf
langref.html.in text eol=lf
deps/* linguist-vendored

View File

@ -70,6 +70,7 @@ pub fn build(b: *Builder) !void {
const skip_release_fast = b.option(bool, "skip-release-fast", "Main test suite skips release-fast builds") orelse skip_release;
const skip_release_safe = b.option(bool, "skip-release-safe", "Main test suite skips release-safe builds") orelse skip_release;
const skip_non_native = b.option(bool, "skip-non-native", "Main test suite skips non-native builds") orelse false;
const skip_libc = b.option(bool, "skip-libc", "Main test suite skips tests that link libc") orelse false;
const skip_self_hosted = b.option(bool, "skip-self-hosted", "Main test suite skips building self hosted compiler") orelse false;
if (!skip_self_hosted) {
// TODO re-enable this after https://github.com/ziglang/zig/issues/2377
@ -96,6 +97,10 @@ pub fn build(b: *Builder) !void {
const test_filter = b.option([]const u8, "test-filter", "Skip tests that do not match filter");
const is_wine_enabled = b.option(bool, "enable-wine", "Use Wine to run cross compiled Windows tests") orelse false;
const is_qemu_enabled = b.option(bool, "enable-qemu", "Use QEMU to run cross compiled foreign architecture tests") orelse false;
const glibc_multi_dir = b.option([]const u8, "enable-foreign-glibc", "Provide directory with glibc installations to run cross compiled tests that link glibc");
const test_stage2_step = b.step("test-stage2", "Run the stage2 compiler tests");
test_stage2_step.dependOn(&test_stage2.step);
@ -122,19 +127,16 @@ pub fn build(b: *Builder) !void {
}
const modes = chosen_modes[0..chosen_mode_index];
const multi_and_single = [_]bool{ false, true };
const just_multi = [_]bool{false};
// run stage1 `zig fmt` on this build.zig file just to make sure it works
test_step.dependOn(&fmt_build_zig.step);
const fmt_step = b.step("test-fmt", "Run zig fmt against build.zig to make sure it works");
fmt_step.dependOn(&fmt_build_zig.step);
test_step.dependOn(tests.addPkgTests(b, test_filter, "test/stage1/behavior.zig", "behavior", "Run the behavior tests", modes, multi_and_single, skip_non_native));
test_step.dependOn(tests.addPkgTests(b, test_filter, "test/stage1/behavior.zig", "behavior", "Run the behavior tests", modes, false, skip_non_native, skip_libc, is_wine_enabled, is_qemu_enabled, glibc_multi_dir));
test_step.dependOn(tests.addPkgTests(b, test_filter, "std/std.zig", "std", "Run the standard library tests", modes, multi_and_single, skip_non_native));
test_step.dependOn(tests.addPkgTests(b, test_filter, "std/std.zig", "std", "Run the standard library tests", modes, false, skip_non_native, skip_libc, is_wine_enabled, is_qemu_enabled, glibc_multi_dir));
test_step.dependOn(tests.addPkgTests(b, test_filter, "std/special/compiler_rt.zig", "compiler-rt", "Run the compiler_rt tests", modes, just_multi, skip_non_native));
test_step.dependOn(tests.addPkgTests(b, test_filter, "std/special/compiler_rt.zig", "compiler-rt", "Run the compiler_rt tests", modes, true, skip_non_native, true, is_wine_enabled, is_qemu_enabled, glibc_multi_dir));
test_step.dependOn(tests.addCompareOutputTests(b, test_filter, modes));
test_step.dependOn(tests.addStandaloneTests(b, test_filter, modes));

View File

@ -12,7 +12,7 @@ sudo apt-get update -q
sudo apt-get remove -y llvm-*
sudo rm -rf /usr/local/*
sudo apt-get install -y libxml2-dev libclang-9-dev llvm-9 llvm-9-dev cmake s3cmd gcc-7 g++-7
sudo apt-get install -y libxml2-dev libclang-9-dev llvm-9 llvm-9-dev cmake s3cmd gcc-7 g++-7 qemu
export CC=gcc-7
export CXX=g++-7
@ -20,7 +20,7 @@ mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release
make -j2 install
./zig build --build-file ../build.zig test
./zig build test -Denable-qemu
if [ "${BUILD_REASON}" != "PullRequest" ]; then
ARTIFACTSDIR="$BUILDDIR/artifacts"

View File

@ -70,7 +70,7 @@ mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=$PREFIX -DCMAKE_INSTALL_PREFIX=$(pwd)/release -DZIG_STATIC=ON
make $JOBS install
release/bin/zig build --build-file ../build.zig test
release/bin/zig build test
if [ "${BUILD_REASON}" != "PullRequest" ]; then
mv ../LICENSE release/

View File

@ -27,7 +27,7 @@ jobs:
displayName: 'Build and test'
- job: BuildWindows
pool:
vmImage: 'vs2017-win2016'
vmImage: 'windows-2019'
timeoutInMinutes: 360

View File

@ -10,17 +10,18 @@ SET "PATH=%PREVPATH%"
SET "MSYSTEM=%PREVMSYSTEM%"
SET "ZIGBUILDDIR=%SRCROOT%\build"
SET "ZIGINSTALLDIR=%ZIGBUILDDIR%\release"
SET "ZIGINSTALLDIR=%ZIGBUILDDIR%\dist"
SET "ZIGPREFIXPATH=%SRCROOT%\llvm+clang-9.0.0-win64-msvc-release"
call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
call "C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x64
mkdir %ZIGBUILDDIR%
cd %ZIGBUILDDIR%
cmake.exe .. -Thost=x64 -G"Visual Studio 15 2017 Win64" "-DCMAKE_INSTALL_PREFIX=%ZIGINSTALLDIR%" "-DCMAKE_PREFIX_PATH=%ZIGPREFIXPATH%" -DCMAKE_BUILD_TYPE=Release || exit /b
msbuild /p:Configuration=Release INSTALL.vcxproj || exit /b
REM Here we use MinSizeRel instead of Release to work around https://github.com/ziglang/zig/issues/3024
cmake.exe .. -Thost=x64 -G"Visual Studio 16 2019" -A x64 "-DCMAKE_INSTALL_PREFIX=%ZIGINSTALLDIR%" "-DCMAKE_PREFIX_PATH=%ZIGPREFIXPATH%" -DCMAKE_BUILD_TYPE=MinSizeRel || exit /b
msbuild /p:Configuration=MinSizeRel INSTALL.vcxproj || exit /b
"%ZIGINSTALLDIR%\bin\zig.exe" build --build-file ..\build.zig test || exit /b
"%ZIGINSTALLDIR%\bin\zig.exe" build test || exit /b
set "PATH=%CD:~0,2%\msys64\usr\bin;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem"
SET "MSYSTEM=MINGW64"

View File

@ -6,16 +6,15 @@ set -e
if [ "${BUILD_REASON}" != "PullRequest" ]; then
cd "$ZIGBUILDDIR"
rm release/*.exe
mv ../LICENSE release/
mv ../zig-cache/langref.html release/
mv release/bin/zig.exe release/
rmdir release/bin
mv ../LICENSE dist/
mv ../zig-cache/langref.html dist/
mv dist/bin/zig.exe dist/
rmdir dist/bin
VERSION=$(release/zig.exe version)
VERSION=$(dist/zig.exe version)
DIRNAME="zig-windows-x86_64-$VERSION"
TARBALL="$DIRNAME.zip"
mv release "$DIRNAME"
mv dist "$DIRNAME"
7z a "$TARBALL" "$DIRNAME"
mv "$DOWNLOADSECUREFILE_SECUREFILEPATH" "$HOME/.s3cfg"

View File

@ -1938,32 +1938,6 @@ __buildmov(__movsd, unsigned __LONG32, "d")
#define __INTRINSIC_DEFINED___movsd
#endif /* __INTRINSIC_PROLOG */
#if !defined(__GNUC__) || __GNUC__ < 8 /* GCC 8 has already defined _xgetbv */
/* NOTE: This should be in immintrin.h */
#if __INTRINSIC_PROLOG(_xgetbv)
unsigned __int64 _xgetbv(unsigned int);
#if !__has_builtin(_xgetbv)
__INTRINSICS_USEINLINE
unsigned __int64 _xgetbv(unsigned int index)
{
#if defined(__x86_64__) || defined(_AMD64_)
unsigned __int64 val1, val2;
#else
unsigned __LONG32 val1, val2;
#endif /* defined(__x86_64__) || defined(_AMD64_) */
__asm__ __volatile__(
"xgetbv"
: "=a" (val1), "=d" (val2)
: "c" (index));
return (((unsigned __int64)val2) << 32) | val1;
}
#endif
#define __INTRINSIC_DEFINED__xgetbv
#endif /* __INTRINSIC_PROLOG */
#endif /* __GNUC__ < 8 */
#endif /* defined(__x86_64__) || defined(_AMD64_) || defined(__i386__) || defined(_X86_) */
/* ***************************************************** */

View File

@ -61,7 +61,6 @@ void buf_appendf(Buf *buf, const char *format, ...) {
// these functions are not static inline so they can be better used as template parameters
bool buf_eql_buf(Buf *buf, Buf *other) {
assert(buf->list.length);
return buf_eql_mem(buf, buf_ptr(other), buf_len(other));
}

View File

@ -50,7 +50,7 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo
}
{
SplitIterator it = memSplit(buf_to_slice(vers_txt_contents), str("\n"));
SplitIterator it = memSplit(buf_to_slice(vers_txt_contents), str("\r\n"));
for (;;) {
Optional<Slice<uint8_t>> opt_component = SplitIterator_next(&it);
if (!opt_component.is_some) break;
@ -65,7 +65,7 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo
}
}
{
SplitIterator it = memSplit(buf_to_slice(fns_txt_contents), str("\n"));
SplitIterator it = memSplit(buf_to_slice(fns_txt_contents), str("\r\n"));
for (;;) {
Optional<Slice<uint8_t>> opt_component = SplitIterator_next(&it);
if (!opt_component.is_some) break;
@ -91,17 +91,19 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo
}
}
{
SplitIterator it = memSplit(buf_to_slice(abi_txt_contents), str("\n"));
SplitIterator it = memSplit(buf_to_slice(abi_txt_contents), str("\r\n"));
ZigGLibCVerList *ver_list_base = nullptr;
int line_num = 0;
for (;;) {
if (ver_list_base == nullptr) {
line_num += 1;
Optional<Slice<uint8_t>> opt_line = SplitIterator_next_separate(&it);
if (!opt_line.is_some) break;
ver_list_base = allocate<ZigGLibCVerList>(glibc_abi->all_functions.length);
ZigTarget *target = allocate<ZigTarget>(1);
SplitIterator line_it = memSplit(opt_line.value, str(" "));
for (;;) {
ZigTarget *target = allocate<ZigTarget>(1);
Optional<Slice<uint8_t>> opt_target = SplitIterator_next(&line_it);
if (!opt_target.is_some) break;
@ -122,7 +124,19 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo
target->os = OsLinux;
err = target_parse_abi(&target->abi, (char*)opt_abi.value.ptr, opt_abi.value.len);
assert(err == ErrorNone);
if (err != ErrorNone) {
fprintf(stderr, "Error parsing %s:%d: %s\n", buf_ptr(glibc_abi->abi_txt_path),
line_num, err_str(err));
fprintf(stderr, "arch: '%.*s', os: '%.*s', abi: '%.*s'\n",
(int)opt_arch.value.len, (const char*)opt_arch.value.ptr,
(int)opt_os.value.len, (const char*)opt_os.value.ptr,
(int)opt_abi.value.len, (const char*)opt_abi.value.ptr);
fprintf(stderr, "parsed from target: '%.*s'\n",
(int)opt_target.value.len, (const char*)opt_target.value.ptr);
fprintf(stderr, "parsed from line:\n%.*s\n", (int)opt_line.value.len, opt_line.value.ptr);
fprintf(stderr, "Zig installation appears to be corrupted.\n");
exit(1);
}
glibc_abi->version_table.put(target, ver_list_base);
}
@ -130,6 +144,7 @@ Error glibc_load_metadata(ZigGLibCAbi **out_result, Buf *zig_lib_dir, bool verbo
}
for (size_t fn_i = 0; fn_i < glibc_abi->all_functions.length; fn_i += 1) {
ZigGLibCVerList *ver_list = &ver_list_base[fn_i];
line_num += 1;
Optional<Slice<uint8_t>> opt_line = SplitIterator_next_separate(&it);
assert(opt_line.is_some);
@ -266,7 +281,7 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con
// - If there are no versions, don't emit it
// - Take the greatest one <= than the target one
// - If none of them is <= than the
// specified one don't pick any default version
// specified one don't pick any default version
if (ver_list->len == 0) continue;
uint8_t chosen_def_ver_index = 255;
for (uint8_t ver_i = 0; ver_i < ver_list->len; ver_i += 1) {
@ -322,7 +337,7 @@ Error glibc_build_dummies_and_maps(CodeGen *g, const ZigGLibCAbi *glibc_abi, con
codegen_set_lib_version(child_gen, lib->sover, 0, 0);
child_gen->is_dynamic = true;
child_gen->is_dummy_so = true;
child_gen->version_script_path = map_file_path;
child_gen->version_script_path = map_file_path;
child_gen->enable_cache = false;
child_gen->output_dir = dummy_dir;
codegen_build_and_link(child_gen);

View File

@ -1295,6 +1295,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
c_file->args.append("-include");
c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h"));
c_file->args.append("-DMODULE_NAME=libc");
c_file->args.append("-Wno-nonportable-include-path");
c_file->args.append("-include");
c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h"));
c_file->args.append("-DTOP_NAMESPACE=glibc");
@ -1321,6 +1322,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
c_file->args.append("-include");
c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h"));
c_file->args.append("-DMODULE_NAME=libc");
c_file->args.append("-Wno-nonportable-include-path");
c_file->args.append("-include");
c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h"));
c_file->args.append("-DPIC");
@ -1377,6 +1379,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
c_file->args.append("-include");
c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h"));
c_file->args.append("-DMODULE_NAME=libc");
c_file->args.append("-Wno-nonportable-include-path");
c_file->args.append("-include");
c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h"));
c_file->args.append("-DPIC");
@ -1420,6 +1423,7 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) {
c_file->args.append("-include");
c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-modules.h"));
c_file->args.append("-DMODULE_NAME=libc");
c_file->args.append("-Wno-nonportable-include-path");
c_file->args.append("-include");
c_file->args.append(path_from_libc(parent, "glibc" OS_SEP "include" OS_SEP "libc-symbols.h"));
c_file->args.append("-DPIC");

View File

@ -116,7 +116,7 @@ static void os_spawn_process_posix(ZigList<const char *> &args, Termination *ter
pid_t pid;
int rc = posix_spawnp(&pid, args.at(0), nullptr, nullptr, const_cast<char *const*>(argv), environ);
if (rc != 0) {
zig_panic("posix_spawn failed: %s", strerror(rc));
zig_panic("unable to spawn %s: %s", args.at(0), strerror(rc));
}
int status;

View File

@ -18,17 +18,10 @@ void zig_panic(const char *format, ...) {
vfprintf(stderr, format, ap);
fflush(stderr);
va_end(ap);
stage2_panic(nullptr, 0);
stage2_panic("", 0);
abort();
}
void assert(bool ok) {
if (!ok) {
const char *msg = "Assertion failed. This is a bug in the Zig compiler.";
stage2_panic(msg, strlen(msg));
}
}
uint32_t int_hash(int i) {
return (uint32_t)(i % UINT32_MAX);
}

View File

@ -43,15 +43,21 @@ ATTRIBUTE_NORETURN
ATTRIBUTE_PRINTF(1, 2)
void zig_panic(const char *format, ...);
static inline void zig_assert(bool ok, const char *file, int line, const char *func) {
if (!ok) {
zig_panic("Assertion failed at %s:%d in %s. This is a bug in the Zig compiler.", file, line, func);
}
}
#ifdef _WIN32
#define __func__ __FUNCTION__
#endif
#define zig_unreachable() zig_panic("unreachable: %s:%s:%d", __FILE__, __func__, __LINE__)
#define zig_unreachable() zig_panic("Unreachable at %s:%d in %s. This is a bug in the Zig compiler.", __FILE__, __LINE__, __func__)
// Assertions in stage1 are always on, and they call zig @panic.
#undef assert
void assert(bool ok);
#define assert(ok) zig_assert(ok, __FILE__, __LINE__, __func__)
#if defined(_MSC_VER)
static inline int clzll(unsigned long long mask) {

View File

@ -1015,6 +1015,7 @@ pub const Target = union(enum) {
=> return .msvc,
.linux,
.wasi,
.emscripten,
=> return .musl,
}
}
@ -1175,6 +1176,13 @@ pub const Target = union(enum) {
};
}
pub fn isLinux(self: Target) bool {
return switch (self.getOs()) {
.linux => true,
else => false,
};
}
pub fn isUefi(self: Target) bool {
return switch (self.getOs()) {
.uefi => true,
@ -1196,9 +1204,125 @@ pub const Target = union(enum) {
};
}
pub fn isNetBSD(self: Target) bool {
return switch (self.getOs()) {
.netbsd => true,
else => false,
};
}
pub fn wantSharedLibSymLinks(self: Target) bool {
return !self.isWindows();
}
pub fn osRequiresLibC(self: Target) bool {
return self.isDarwin() or self.isFreeBSD() or self.isNetBSD();
}
pub fn getArchPtrBitWidth(self: Target) u32 {
switch (self.getArch()) {
.avr,
.msp430,
=> return 16,
.arc,
.arm,
.armeb,
.hexagon,
.le32,
.mips,
.mipsel,
.powerpc,
.r600,
.riscv32,
.sparc,
.sparcel,
.tce,
.tcele,
.thumb,
.thumbeb,
.i386,
.xcore,
.nvptx,
.amdil,
.hsail,
.spir,
.kalimba,
.shave,
.lanai,
.wasm32,
.renderscript32,
.aarch64_32,
=> return 32,
.aarch64,
.aarch64_be,
.mips64,
.mips64el,
.powerpc64,
.powerpc64le,
.riscv64,
.x86_64,
.nvptx64,
.le64,
.amdil64,
.hsail64,
.spir64,
.wasm64,
.renderscript64,
.amdgcn,
.bpfel,
.bpfeb,
.sparcv9,
.s390x,
=> return 64,
}
}
pub const Executor = union(enum) {
native,
qemu: []const u8,
wine: []const u8,
unavailable,
};
pub fn getExternalExecutor(self: Target) Executor {
if (@TagType(Target)(self) == .Native) return .native;
// If the target OS matches the host OS, we can use QEMU to emulate a foreign architecture.
if (self.getOs() == builtin.os) {
return switch (self.getArch()) {
.aarch64 => Executor{ .qemu = "qemu-aarch64" },
.aarch64_be => Executor{ .qemu = "qemu-aarch64_be" },
.arm => Executor{ .qemu = "qemu-arm" },
.armeb => Executor{ .qemu = "qemu-armeb" },
.i386 => Executor{ .qemu = "qemu-i386" },
.mips => Executor{ .qemu = "qemu-mips" },
.mipsel => Executor{ .qemu = "qemu-mipsel" },
.mips64 => Executor{ .qemu = "qemu-mips64" },
.mips64el => Executor{ .qemu = "qemu-mips64el" },
.powerpc => Executor{ .qemu = "qemu-ppc" },
.powerpc64 => Executor{ .qemu = "qemu-ppc64" },
.powerpc64le => Executor{ .qemu = "qemu-ppc64le" },
.riscv32 => Executor{ .qemu = "qemu-riscv32" },
.riscv64 => Executor{ .qemu = "qemu-riscv64" },
.s390x => Executor{ .qemu = "qemu-s390x" },
.sparc => Executor{ .qemu = "qemu-sparc" },
.x86_64 => Executor{ .qemu = "qemu-x86_64" },
else => return .unavailable,
};
}
if (self.isWindows()) {
switch (self.getArchPtrBitWidth()) {
32 => return Executor{ .wine = "wine" },
64 => return Executor{ .wine = "wine64" },
else => return .unavailable,
}
}
return .unavailable;
}
};
const Pkg = struct {
@ -1266,6 +1390,7 @@ pub const LibExeObjStep = struct {
include_dirs: ArrayList(IncludeDir),
output_dir: ?[]const u8,
need_system_paths: bool,
is_linking_libc: bool = false,
installed_path: ?[]const u8,
install_step: ?*InstallArtifactStep,
@ -1275,6 +1400,20 @@ pub const LibExeObjStep = struct {
valgrind_support: ?bool = null,
/// Uses system Wine installation to run cross compiled Windows build artifacts.
enable_wine: bool = false,
/// Uses system QEMU installation to run cross compiled foreign architecture build artifacts.
enable_qemu: bool = false,
/// After following the steps in https://github.com/ziglang/zig/wiki/Updating-libc#glibc,
/// this will be the directory $glibc-build-dir/install/glibcs
/// Given the example of the aarch64 target, this is the directory
/// that contains the path `aarch64-linux-gnu/lib/ld-linux-aarch64.so.1`.
glibc_multi_install_dir: ?[]const u8 = null,
dynamic_linker: ?[]const u8 = null,
const LinkObject = union(enum) {
StaticPath: []const u8,
OtherStep: *LibExeObjStep,
@ -1504,7 +1643,9 @@ pub const LibExeObjStep = struct {
pub fn linkSystemLibrary(self: *LibExeObjStep, name: []const u8) void {
self.link_objects.append(LinkObject{ .SystemLib = self.builder.dupe(name) }) catch unreachable;
if (!isLibCLibrary(name)) {
if (isLibCLibrary(name)) {
self.is_linking_libc = true;
} else {
self.need_system_paths = true;
}
}
@ -1840,6 +1981,11 @@ pub const LibExeObjStep = struct {
zig_args.append(builder.pathFromRoot(linker_script)) catch unreachable;
}
if (self.dynamic_linker) |dynamic_linker| {
try zig_args.append("--dynamic-linker");
try zig_args.append(dynamic_linker);
}
if (self.version_script) |version_script| {
try zig_args.append("--version-script");
try zig_args.append(builder.pathFromRoot(version_script));
@ -1854,6 +2000,34 @@ pub const LibExeObjStep = struct {
try zig_args.append("--test-cmd-bin");
}
}
} else switch (self.target.getExternalExecutor()) {
.native, .unavailable => {},
.qemu => |bin_name| if (self.enable_qemu) qemu: {
const need_cross_glibc = self.target.isGnu() and self.target.isLinux() and self.is_linking_libc;
const glibc_dir_arg = if (need_cross_glibc)
self.glibc_multi_install_dir orelse break :qemu
else
null;
try zig_args.append("--test-cmd");
try zig_args.append(bin_name);
if (glibc_dir_arg) |dir| {
const full_dir = try fs.path.join(builder.allocator, [_][]const u8{
dir,
try self.target.linuxTriple(builder.allocator),
});
try zig_args.append("--test-cmd");
try zig_args.append("-L");
try zig_args.append("--test-cmd");
try zig_args.append(full_dir);
}
try zig_args.append("--test-cmd-bin");
},
.wine => |bin_name| if (self.enable_wine) {
try zig_args.append("--test-cmd");
try zig_args.append(bin_name);
try zig_args.append("--test-cmd-bin");
},
}
for (self.packages.toSliceConst()) |pkg| {
zig_args.append("--pkg-begin") catch unreachable;

View File

@ -63,7 +63,7 @@ pub extern "c" fn close(fd: fd_t) c_int;
pub extern "c" fn @"close$NOCANCEL"(fd: fd_t) c_int;
pub extern "c" fn fstat(fd: fd_t, buf: *Stat) c_int;
pub extern "c" fn @"fstat$INODE64"(fd: fd_t, buf: *Stat) c_int;
pub extern "c" fn lseek(fd: fd_t, offset: isize, whence: c_int) isize;
pub extern "c" fn lseek(fd: fd_t, offset: off_t, whence: c_int) off_t;
pub extern "c" fn open(path: [*]const u8, oflag: c_uint, ...) c_int;
pub extern "c" fn openat(fd: c_int, path: [*]const u8, oflag: c_uint, ...) c_int;
pub extern "c" fn raise(sig: c_int) c_int;

View File

@ -382,6 +382,10 @@ pub fn parseFloat(comptime T: type, s: []const u8) !T {
}
test "fmt.parseFloat" {
if (@import("builtin").arch == .arm) {
// TODO https://github.com/ziglang/zig/issues/3289
return error.SkipZigTest;
}
const testing = std.testing;
const expect = testing.expect;
const expectEqual = testing.expectEqual;

View File

@ -646,6 +646,10 @@ test "resolve" {
}
test "resolveWindows" {
if (@import("builtin").arch == .aarch64) {
// TODO https://github.com/ziglang/zig/issues/3288
return error.SkipZigTest;
}
if (windows.is_the_target) {
const cwd = try process.getCwdAlloc(debug.global_allocator);
const parsed_cwd = windowsParsePath(cwd);
@ -1086,6 +1090,10 @@ pub fn relativePosix(allocator: *Allocator, from: []const u8, to: []const u8) ![
}
test "relative" {
if (@import("builtin").arch == .aarch64) {
// TODO https://github.com/ziglang/zig/issues/3288
return error.SkipZigTest;
}
testRelativeWindows("c:/blah\\blah", "d:/games", "D:\\games");
testRelativeWindows("c:/aaaa/bbbb", "c:/aaaa", "..");
testRelativeWindows("c:/aaaa/bbbb", "c:/cccc", "..\\..\\cccc");

View File

@ -11,6 +11,10 @@ const fs = std.fs;
const File = std.fs.File;
test "write a file, read it, then delete it" {
if (builtin.arch == .aarch64 and builtin.glibc_version != null) {
// TODO https://github.com/ziglang/zig/issues/3288
return error.SkipZigTest;
}
var raw_bytes: [200 * 1024]u8 = undefined;
var allocator = &std.heap.FixedBufferAllocator.init(raw_bytes[0..]).allocator;

View File

@ -43,6 +43,8 @@ pub const mach_timebase_info_data = extern struct {
denom: u32,
};
pub const off_t = i64;
/// Renamed to Stat to not conflict with the stat function.
/// atime, mtime, and ctime have functions to return `timespec`,
/// because although this is a POSIX API, the layout and names of
@ -65,7 +67,7 @@ pub const Stat = extern struct {
ctimensec: isize,
birthtimesec: isize,
birthtimensec: isize,
size: i64,
size: off_t,
blocks: i64,
blksize: i32,
flags: u32,

View File

@ -73,6 +73,8 @@ pub const msghdr_const = extern struct {
msg_flags: i32,
};
pub const off_t = i64;
/// Renamed to Stat to not conflict with the stat function.
/// atime, mtime, and ctime have functions to return `timespec`,
/// because although this is a POSIX API, the layout and names of
@ -96,7 +98,7 @@ pub const Stat = extern struct {
ctim: timespec,
birthtim: timespec,
size: i64,
size: off_t,
blocks: i64,
blksize: isize,
flags: u32,

View File

@ -511,6 +511,8 @@ pub const msghdr_const = extern struct {
msg_flags: i32,
};
pub const off_t = i64;
/// Renamed to Stat to not conflict with the stat function.
/// atime, mtime, and ctime have functions to return `timespec`,
/// because although this is a POSIX API, the layout and names of
@ -527,7 +529,7 @@ pub const Stat = extern struct {
gid: u32,
rdev: u64,
__rdev_padding: u32,
size: i64,
size: off_t,
blksize: i32,
blocks: u64,
atim: timespec,

View File

@ -1,11 +1,13 @@
// arm64-specific declarations that are intended to be imported into the POSIX namespace.
// This does include Linux-only APIs.
const std = @import("../../std.zig");
const std = @import("../../../std.zig");
const linux = std.os.linux;
const socklen_t = linux.socklen_t;
const iovec = linux.iovec;
const iovec_const = linux.iovec_const;
const uid_t = linux.uid_t;
const gid_t = linux.gid_t;
pub const SYS_io_setup = 0;
pub const SYS_io_destroy = 1;
@ -382,6 +384,15 @@ pub const msghdr_const = extern struct {
msg_flags: i32,
};
pub const blksize_t = i32;
pub const nlink_t = u32;
pub const time_t = isize;
pub const mode_t = u32;
pub const off_t = isize;
pub const ino_t = usize;
pub const dev_t = usize;
pub const blkcnt_t = isize;
/// Renamed to Stat to not conflict with the stat function.
/// atime, mtime, and ctime have functions to return `timespec`,
/// because although this is a POSIX API, the layout and names of
@ -389,23 +400,22 @@ pub const msghdr_const = extern struct {
/// in C, macros are used to hide the differences. Here we use
/// methods to accomplish this.
pub const Stat = extern struct {
dev: u64,
ino: u64,
nlink: usize,
mode: u32,
uid: u32,
gid: u32,
__pad0: u32,
rdev: u64,
size: i64,
blksize: isize,
blocks: i64,
dev: dev_t,
ino: ino_t,
mode: mode_t,
nlink: nlink_t,
uid: uid_t,
gid: gid_t,
rdev: dev_t,
__pad: usize,
size: off_t,
blksize: blksize_t,
__pad2: i32,
blocks: blkcnt_t,
atim: timespec,
mtim: timespec,
ctim: timespec,
__unused: [3]isize,
__unused: [2]u32,
pub fn atime(self: Stat) timespec {
return self.atim;
@ -421,7 +431,7 @@ pub const Stat = extern struct {
};
pub const timespec = extern struct {
tv_sec: isize,
tv_sec: time_t,
tv_nsec: isize,
};

View File

@ -479,6 +479,8 @@ pub const msghdr_const = extern struct {
msg_flags: i32,
};
pub const off_t = i64;
/// Renamed to Stat to not conflict with the stat function.
/// atime, mtime, and ctime have functions to return `timespec`,
/// because although this is a POSIX API, the layout and names of
@ -495,7 +497,7 @@ pub const Stat = extern struct {
gid: u32,
__pad0: u32,
rdev: u64,
size: i64,
size: off_t,
blksize: isize,
blocks: i64,

View File

@ -73,6 +73,8 @@ pub const msghdr_const = extern struct {
msg_flags: i32,
};
pub const off_t = i64;
/// Renamed to Stat to not conflict with the stat function.
/// atime, mtime, and ctime have functions to return `timespec`,
/// because although this is a POSIX API, the layout and names of
@ -94,7 +96,7 @@ pub const Stat = extern struct {
ctim: timespec,
birthtim: timespec,
size: i64,
size: off_t,
blocks: i64,
blksize: isize,
flags: u32,

View File

@ -95,6 +95,10 @@ test "cpu count" {
}
test "AtomicFile" {
if (builtin.arch == .aarch64 and builtin.glibc_version != null) {
// TODO https://github.com/ziglang/zig/issues/3288
return error.SkipZigTest;
}
var buffer: [1024]u8 = undefined;
const allocator = &std.heap.FixedBufferAllocator.init(buffer[0..]).allocator;
const test_out_file = "tmp_atomic_file_test_dest.txt";

View File

@ -511,6 +511,11 @@ fn testCompare(l: *Node, r: *Node) mem.Compare {
}
test "rb" {
if (@import("builtin").arch == .aarch64) {
// TODO https://github.com/ziglang/zig/issues/3288
return error.SkipZigTest;
}
var tree: Tree = undefined;
var ns: [10]testNumber = undefined;
ns[0].value = 42;
@ -571,6 +576,10 @@ test "inserting and looking up" {
}
test "multiple inserts, followed by calling first and last" {
if (@import("builtin").arch == .aarch64) {
// TODO https://github.com/ziglang/zig/issues/3288
return error.SkipZigTest;
}
var tree: Tree = undefined;
tree.init(testCompare);
var zeroth: testNumber = undefined;

View File

@ -143,7 +143,7 @@ comptime {
@export("__negsf2", @import("compiler_rt/negXf2.zig").__negsf2, linkage);
@export("__negdf2", @import("compiler_rt/negXf2.zig").__negdf2, linkage);
if (is_arm_arch and !is_arm_64) {
if (is_arm_arch and !is_arm_64 and !is_test) {
@export("__aeabi_unwind_cpp_pr0", __aeabi_unwind_cpp_pr0, strong_linkage);
@export("__aeabi_unwind_cpp_pr1", __aeabi_unwind_cpp_pr1, linkage);
@export("__aeabi_unwind_cpp_pr2", __aeabi_unwind_cpp_pr2, linkage);
@ -233,7 +233,7 @@ comptime {
@export("__aeabi_dcmpgt", @import("compiler_rt/arm/aeabi_dcmp.zig").__aeabi_dcmpgt, linkage);
@export("__aeabi_dcmpun", @import("compiler_rt/comparedf2.zig").__unorddf2, linkage);
}
if (builtin.os == builtin.Os.windows) {
if (builtin.os == .windows) {
if (!builtin.link_libc) {
@export("_chkstk", @import("compiler_rt/stack_probe.zig")._chkstk, strong_linkage);
@export("__chkstk", @import("compiler_rt/stack_probe.zig").__chkstk, strong_linkage);
@ -247,11 +247,11 @@ comptime {
}
switch (builtin.arch) {
builtin.Arch.i386 => {
.i386 => {
@export("_aulldiv", @import("compiler_rt/aulldiv.zig")._aulldiv, strong_linkage);
@export("_aullrem", @import("compiler_rt/aullrem.zig")._aullrem, strong_linkage);
},
builtin.Arch.x86_64 => {
.x86_64 => {
// The "ti" functions must use @Vector(2, u64) parameter types to adhere to the ABI
// that LLVM expects compiler-rt to have.
@export("__divti3", @import("compiler_rt/divti3.zig").__divti3_windows_x86_64, linkage);
@ -264,6 +264,9 @@ comptime {
else => {},
}
} else {
if (builtin.glibc_version != null) {
@export("__stack_chk_guard", __stack_chk_guard, linkage);
}
@export("__divti3", @import("compiler_rt/divti3.zig").__divti3, linkage);
@export("__modti3", @import("compiler_rt/modti3.zig").__modti3, linkage);
@export("__multi3", @import("compiler_rt/multi3.zig").__multi3, linkage);

View File

@ -14,31 +14,31 @@ const ConditionalOperator = enum {
pub nakedcc fn __aeabi_dcmpeq() noreturn {
@setRuntimeSafety(false);
aeabi_dcmp(.Eq);
@inlineCall(aeabi_dcmp, .Eq);
unreachable;
}
pub nakedcc fn __aeabi_dcmplt() noreturn {
@setRuntimeSafety(false);
aeabi_dcmp(.Lt);
@inlineCall(aeabi_dcmp, .Lt);
unreachable;
}
pub nakedcc fn __aeabi_dcmple() noreturn {
@setRuntimeSafety(false);
aeabi_dcmp(.Le);
@inlineCall(aeabi_dcmp, .Le);
unreachable;
}
pub nakedcc fn __aeabi_dcmpge() noreturn {
@setRuntimeSafety(false);
aeabi_dcmp(.Ge);
@inlineCall(aeabi_dcmp, .Ge);
unreachable;
}
pub nakedcc fn __aeabi_dcmpgt() noreturn {
@setRuntimeSafety(false);
aeabi_dcmp(.Gt);
@inlineCall(aeabi_dcmp, .Gt);
unreachable;
}
@ -49,7 +49,7 @@ inline fn convert_dcmp_args_to_df2_args() void {
);
}
inline fn aeabi_dcmp(comptime cond: ConditionalOperator) void {
fn aeabi_dcmp(comptime cond: ConditionalOperator) void {
@setRuntimeSafety(false);
asm volatile (
\\ push { r4, lr }

View File

@ -14,31 +14,31 @@ const ConditionalOperator = enum {
pub nakedcc fn __aeabi_fcmpeq() noreturn {
@setRuntimeSafety(false);
aeabi_fcmp(.Eq);
@inlineCall(aeabi_fcmp, .Eq);
unreachable;
}
pub nakedcc fn __aeabi_fcmplt() noreturn {
@setRuntimeSafety(false);
aeabi_fcmp(.Lt);
@inlineCall(aeabi_fcmp, .Lt);
unreachable;
}
pub nakedcc fn __aeabi_fcmple() noreturn {
@setRuntimeSafety(false);
aeabi_fcmp(.Le);
@inlineCall(aeabi_fcmp, .Le);
unreachable;
}
pub nakedcc fn __aeabi_fcmpge() noreturn {
@setRuntimeSafety(false);
aeabi_fcmp(.Ge);
@inlineCall(aeabi_fcmp, .Ge);
unreachable;
}
pub nakedcc fn __aeabi_fcmpgt() noreturn {
@setRuntimeSafety(false);
aeabi_fcmp(.Gt);
@inlineCall(aeabi_fcmp, .Gt);
unreachable;
}
@ -49,7 +49,7 @@ inline fn convert_fcmp_args_to_sf2_args() void {
);
}
inline fn aeabi_fcmp(comptime cond: ConditionalOperator) void {
fn aeabi_fcmp(comptime cond: ConditionalOperator) void {
@setRuntimeSafety(false);
asm volatile (
\\ push { r4, lr }

View File

@ -23,21 +23,183 @@ const runtime_safety = @import("runtime_safety.zig");
const translate_c = @import("translate_c.zig");
const gen_h = @import("gen_h.zig");
const cross_targets = [_]CrossTarget{
CrossTarget{
.os = .linux,
.arch = .x86_64,
.abi = .gnu,
const TestTarget = struct {
target: Target = .Native,
mode: builtin.Mode = .Debug,
link_libc: bool = false,
single_threaded: bool = false,
disable_native: bool = false,
};
const test_targets = [_]TestTarget{
TestTarget{},
TestTarget{
.link_libc = true,
},
CrossTarget{
.os = .macosx,
.arch = .x86_64,
.abi = .gnu,
TestTarget{
.single_threaded = true,
},
CrossTarget{
.os = .windows,
.arch = .x86_64,
.abi = .msvc,
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = .x86_64,
.abi = .none,
},
},
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = .x86_64,
.abi = .gnu,
},
},
.link_libc = true,
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = .x86_64,
.abi = .musl,
},
},
.link_libc = true,
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = builtin.Arch{ .aarch64 = builtin.Arch.Arm64.v8_5a },
.abi = .none,
},
},
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = builtin.Arch{ .aarch64 = builtin.Arch.Arm64.v8_5a },
.abi = .musl,
},
},
.link_libc = true,
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = builtin.Arch{ .aarch64 = builtin.Arch.Arm64.v8_5a },
.abi = .gnu,
},
},
.link_libc = true,
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .linux,
.arch = builtin.Arch{ .arm = builtin.Arch.Arm32.v8_5a },
.abi = .none,
},
},
},
// TODO https://github.com/ziglang/zig/issues/3286
//TestTarget{
// .target = Target{
// .Cross = CrossTarget{
// .os = .linux,
// .arch = builtin.Arch{ .arm = builtin.Arch.Arm32.v8_5a },
// .abi = .musleabihf,
// },
// },
// .link_libc = true,
//},
// TODO https://github.com/ziglang/zig/issues/3287
//TestTarget{
// .target = Target{
// .Cross = CrossTarget{
// .os = .linux,
// .arch = builtin.Arch{ .arm = builtin.Arch.Arm32.v8_5a },
// .abi = .gnueabihf,
// },
// },
// .link_libc = true,
//},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .macosx,
.arch = .x86_64,
.abi = .gnu,
},
},
// TODO https://github.com/ziglang/zig/issues/3295
.disable_native = true,
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .windows,
.arch = .x86_64,
.abi = .msvc,
},
},
},
TestTarget{
.target = Target{
.Cross = CrossTarget{
.os = .windows,
.arch = .x86_64,
.abi = .gnu,
},
},
.link_libc = true,
},
// Do the release tests last because they take a long time
TestTarget{
.mode = .ReleaseFast,
},
TestTarget{
.link_libc = true,
.mode = .ReleaseFast,
},
TestTarget{
.mode = .ReleaseFast,
.single_threaded = true,
},
TestTarget{
.mode = .ReleaseSafe,
},
TestTarget{
.link_libc = true,
.mode = .ReleaseSafe,
},
TestTarget{
.mode = .ReleaseSafe,
.single_threaded = true,
},
TestTarget{
.mode = .ReleaseSmall,
},
TestTarget{
.link_libc = true,
.mode = .ReleaseSmall,
},
TestTarget{
.mode = .ReleaseSmall,
.single_threaded = true,
},
};
@ -182,57 +344,77 @@ pub fn addPkgTests(
name: []const u8,
desc: []const u8,
modes: []const Mode,
single_threaded_list: []const bool,
skip_single_threaded: bool,
skip_non_native: bool,
skip_libc: bool,
is_wine_enabled: bool,
is_qemu_enabled: bool,
glibc_dir: ?[]const u8,
) *build.Step {
const step = b.step(b.fmt("test-{}", name), desc);
var targets = std.ArrayList(*const CrossTarget).init(b.allocator);
defer targets.deinit();
const host = CrossTarget{ .os = builtin.os, .arch = builtin.arch, .abi = builtin.abi };
targets.append(&host) catch unreachable;
for (cross_targets) |*t| {
if (t.os == builtin.os and t.arch == builtin.arch and t.abi == builtin.abi) continue;
targets.append(t) catch unreachable;
}
for (targets.toSliceConst()) |test_target| {
const is_native = (test_target.os == builtin.os and test_target.arch == builtin.arch);
if (skip_non_native and !is_native)
for (test_targets) |test_target| {
if (skip_non_native and test_target.target != .Native)
continue;
if (skip_libc and test_target.link_libc)
continue;
if (test_target.link_libc and test_target.target.osRequiresLibC()) {
// This would be a redundant test.
continue;
for (modes) |mode| {
for ([_]bool{ false, true }) |link_libc| {
for (single_threaded_list) |single_threaded| {
if (link_libc and !is_native) {
// don't assume we have a cross-compiling libc set up
continue;
}
const these_tests = b.addTest(root_src);
these_tests.setNamePrefix(b.fmt(
"{}-{}-{}-{}-{}-{} ",
name,
@tagName(test_target.os),
@tagName(test_target.arch),
@tagName(mode),
if (link_libc) "c" else "bare",
if (single_threaded) "single" else "multi",
));
these_tests.single_threaded = single_threaded;
these_tests.setFilter(test_filter);
these_tests.setBuildMode(mode);
if (!is_native) {
these_tests.setTarget(test_target.arch, test_target.os, test_target.abi);
}
if (link_libc) {
these_tests.linkSystemLibrary("c");
}
if (mem.eql(u8, name, "std")) {
these_tests.overrideStdDir("std");
}
step.dependOn(&these_tests.step);
}
}
}
if (skip_single_threaded and test_target.single_threaded)
continue;
const ArchTag = @TagType(builtin.Arch);
if (test_target.disable_native and
test_target.target.getOs() == builtin.os and
ArchTag(test_target.target.getArch()) == ArchTag(builtin.arch))
{
continue;
}
const want_this_mode = for (modes) |m| {
if (m == test_target.mode) break true;
} else false;
if (!want_this_mode) continue;
const libc_prefix = if (test_target.target.osRequiresLibC())
""
else if (test_target.link_libc)
"c"
else
"bare";
const triple_prefix = if (test_target.target == .Native)
([]const u8)("native")
else
test_target.target.zigTripleNoSubArch(b.allocator) catch unreachable;
const these_tests = b.addTest(root_src);
these_tests.setNamePrefix(b.fmt(
"{}-{}-{}-{}-{} ",
name,
triple_prefix,
@tagName(test_target.mode),
libc_prefix,
if (test_target.single_threaded) "single" else "multi",
));
these_tests.single_threaded = test_target.single_threaded;
these_tests.setFilter(test_filter);
these_tests.setBuildMode(test_target.mode);
these_tests.setTheTarget(test_target.target);
if (test_target.link_libc) {
these_tests.linkSystemLibrary("c");
}
these_tests.overrideStdDir("std");
these_tests.enable_wine = is_wine_enabled;
these_tests.enable_qemu = is_qemu_enabled;
these_tests.glibc_multi_install_dir = glibc_dir;
step.dependOn(&these_tests.step);
}
return step;
}