mirror of
https://github.com/ziglang/zig.git
synced 2025-12-27 00:23:22 +00:00
Merge pull request #12265 from ziglang/stage3-run-translated-c
CI: test-run-translated-c with stage3
This commit is contained in:
commit
c650ccfca7
@ -52,22 +52,22 @@ stage2/bin/zig build -p stage3 -Dstatic-llvm -Dtarget=native-native-musl --searc
|
||||
stage3/bin/zig build # test building self-hosted without LLVM
|
||||
stage3/bin/zig build -Dtarget=arm-linux-musleabihf # test building self-hosted for 32-bit arm
|
||||
|
||||
stage3/bin/zig build test-compiler-rt -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-behavior -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-std -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-universal-libc -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-compare-output -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-asm-link -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-fmt -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-translate-c -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-standalone -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-cli -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-compiler-rt -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-behavior -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-std -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-universal-libc -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-compare-output -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-asm-link -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-fmt -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-translate-c -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-run-translated-c -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-standalone -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-cli -fqemu -fwasmtime -Denable-llvm
|
||||
# https://github.com/ziglang/zig/issues/12144
|
||||
stage3/bin/zig build test-cases -fqemu -fwasmtime
|
||||
stage3/bin/zig build test-link -fqemu -fwasmtime -Denable-llvm
|
||||
stage3/bin/zig build test-cases -fqemu -fwasmtime
|
||||
stage3/bin/zig build test-link -fqemu -fwasmtime -Denable-llvm
|
||||
|
||||
$STAGE1_ZIG build test-stack-traces -fqemu -fwasmtime
|
||||
$STAGE1_ZIG build test-run-translated-c -fqemu -fwasmtime
|
||||
$STAGE1_ZIG build docs -fqemu -fwasmtime
|
||||
|
||||
# Produce the experimental std lib documentation.
|
||||
|
||||
@ -10282,11 +10282,11 @@ const GenZir = struct {
|
||||
try astgen.extra.ensureUnusedCapacity(
|
||||
gpa,
|
||||
@typeInfo(Zir.Inst.FuncFancy).Struct.fields.len +
|
||||
fancyFnExprExtraLen(align_body, args.align_ref) +
|
||||
fancyFnExprExtraLen(addrspace_body, args.addrspace_ref) +
|
||||
fancyFnExprExtraLen(section_body, args.section_ref) +
|
||||
fancyFnExprExtraLen(cc_body, args.cc_ref) +
|
||||
fancyFnExprExtraLen(ret_body, ret_ref) +
|
||||
fancyFnExprExtraLen(astgen, align_body, args.align_ref) +
|
||||
fancyFnExprExtraLen(astgen, addrspace_body, args.addrspace_ref) +
|
||||
fancyFnExprExtraLen(astgen, section_body, args.section_ref) +
|
||||
fancyFnExprExtraLen(astgen, cc_body, args.cc_ref) +
|
||||
fancyFnExprExtraLen(astgen, ret_body, ret_ref) +
|
||||
body_len + src_locs.len +
|
||||
@boolToInt(args.lib_name != 0) +
|
||||
@boolToInt(args.noalias_bits != 0),
|
||||
@ -10322,36 +10322,36 @@ const GenZir = struct {
|
||||
|
||||
const zir_datas = astgen.instructions.items(.data);
|
||||
if (align_body.len != 0) {
|
||||
astgen.extra.appendAssumeCapacity(@intCast(u32, align_body.len));
|
||||
astgen.extra.appendSliceAssumeCapacity(align_body);
|
||||
astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, align_body));
|
||||
astgen.appendBodyWithFixups(align_body);
|
||||
zir_datas[align_body[align_body.len - 1]].@"break".block_inst = new_index;
|
||||
} else if (args.align_ref != .none) {
|
||||
astgen.extra.appendAssumeCapacity(@enumToInt(args.align_ref));
|
||||
}
|
||||
if (addrspace_body.len != 0) {
|
||||
astgen.extra.appendAssumeCapacity(@intCast(u32, addrspace_body.len));
|
||||
astgen.extra.appendSliceAssumeCapacity(addrspace_body);
|
||||
astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, addrspace_body));
|
||||
astgen.appendBodyWithFixups(addrspace_body);
|
||||
zir_datas[addrspace_body[addrspace_body.len - 1]].@"break".block_inst = new_index;
|
||||
} else if (args.addrspace_ref != .none) {
|
||||
astgen.extra.appendAssumeCapacity(@enumToInt(args.addrspace_ref));
|
||||
}
|
||||
if (section_body.len != 0) {
|
||||
astgen.extra.appendAssumeCapacity(@intCast(u32, section_body.len));
|
||||
astgen.extra.appendSliceAssumeCapacity(section_body);
|
||||
astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, section_body));
|
||||
astgen.appendBodyWithFixups(section_body);
|
||||
zir_datas[section_body[section_body.len - 1]].@"break".block_inst = new_index;
|
||||
} else if (args.section_ref != .none) {
|
||||
astgen.extra.appendAssumeCapacity(@enumToInt(args.section_ref));
|
||||
}
|
||||
if (cc_body.len != 0) {
|
||||
astgen.extra.appendAssumeCapacity(@intCast(u32, cc_body.len));
|
||||
astgen.extra.appendSliceAssumeCapacity(cc_body);
|
||||
astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, cc_body));
|
||||
astgen.appendBodyWithFixups(cc_body);
|
||||
zir_datas[cc_body[cc_body.len - 1]].@"break".block_inst = new_index;
|
||||
} else if (args.cc_ref != .none) {
|
||||
astgen.extra.appendAssumeCapacity(@enumToInt(args.cc_ref));
|
||||
}
|
||||
if (ret_body.len != 0) {
|
||||
astgen.extra.appendAssumeCapacity(@intCast(u32, ret_body.len));
|
||||
astgen.extra.appendSliceAssumeCapacity(ret_body);
|
||||
astgen.extra.appendAssumeCapacity(countBodyLenAfterFixups(astgen, ret_body));
|
||||
astgen.appendBodyWithFixups(ret_body);
|
||||
zir_datas[ret_body[ret_body.len - 1]].@"break".block_inst = new_index;
|
||||
} else if (ret_ref != .none) {
|
||||
astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref));
|
||||
@ -10389,11 +10389,12 @@ const GenZir = struct {
|
||||
try astgen.extra.ensureUnusedCapacity(
|
||||
gpa,
|
||||
@typeInfo(Zir.Inst.Func).Struct.fields.len + 1 +
|
||||
@maximum(ret_body.len, @boolToInt(ret_ref != .none)) +
|
||||
fancyFnExprExtraLen(astgen, ret_body, ret_ref) +
|
||||
body_len + src_locs.len,
|
||||
);
|
||||
|
||||
const ret_body_len = if (ret_body.len != 0)
|
||||
@intCast(u32, ret_body.len)
|
||||
countBodyLenAfterFixups(astgen, ret_body)
|
||||
else
|
||||
@boolToInt(ret_ref != .none);
|
||||
|
||||
@ -10404,7 +10405,7 @@ const GenZir = struct {
|
||||
});
|
||||
const zir_datas = astgen.instructions.items(.data);
|
||||
if (ret_body.len != 0) {
|
||||
astgen.extra.appendSliceAssumeCapacity(ret_body);
|
||||
astgen.appendBodyWithFixups(ret_body);
|
||||
zir_datas[ret_body[ret_body.len - 1]].@"break".block_inst = new_index;
|
||||
} else if (ret_ref != .none) {
|
||||
astgen.extra.appendAssumeCapacity(@enumToInt(ret_ref));
|
||||
@ -10435,10 +10436,10 @@ const GenZir = struct {
|
||||
}
|
||||
}
|
||||
|
||||
fn fancyFnExprExtraLen(body: []Zir.Inst.Index, ref: Zir.Inst.Ref) usize {
|
||||
fn fancyFnExprExtraLen(astgen: *AstGen, body: []Zir.Inst.Index, ref: Zir.Inst.Ref) u32 {
|
||||
// In the case of non-empty body, there is one for the body length,
|
||||
// and then one for each instruction.
|
||||
return body.len + @boolToInt(ref != .none);
|
||||
return countBodyLenAfterFixups(astgen, body) + @boolToInt(ref != .none);
|
||||
}
|
||||
|
||||
fn addVar(gz: *GenZir, args: struct {
|
||||
|
||||
@ -3646,6 +3646,24 @@ pub const DeclGen = struct {
|
||||
},
|
||||
.Struct => {
|
||||
const field_ty = parent_ty.structFieldType(field_index);
|
||||
if (parent_ty.containerLayout() == .Packed) {
|
||||
const llvm_usize = dg.context.intType(target.cpu.arch.ptrBitWidth());
|
||||
const base_addr = parent_llvm_ptr.constPtrToInt(llvm_usize);
|
||||
// count bits of fields before this one
|
||||
const prev_bits = b: {
|
||||
var b: usize = 0;
|
||||
for (parent_ty.structFields().values()[0..field_index]) |field| {
|
||||
if (field.is_comptime or !field.ty.hasRuntimeBitsIgnoreComptime()) continue;
|
||||
b += field.ty.bitSize(target);
|
||||
}
|
||||
break :b b;
|
||||
};
|
||||
const byte_offset = llvm_usize.constInt((prev_bits + 7) / 8, .False);
|
||||
const field_addr = base_addr.constAdd(byte_offset);
|
||||
bitcast_needed = false;
|
||||
const final_llvm_ty = (try dg.lowerType(ptr_child_ty)).pointerType(0);
|
||||
break :blk field_addr.constIntToPtr(final_llvm_ty);
|
||||
}
|
||||
bitcast_needed = !field_ty.eql(ptr_child_ty, dg.module);
|
||||
|
||||
var ty_buf: Type.Payload.Pointer = undefined;
|
||||
@ -4473,17 +4491,29 @@ pub const FuncGen = struct {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
const abi_ret_ty = try lowerFnRetTy(self.dg, fn_info);
|
||||
const ptr_abi_ty = abi_ret_ty.pointerType(0);
|
||||
const operand = try self.resolveInst(un_op);
|
||||
const target = self.dg.module.getTarget();
|
||||
const alignment = ret_ty.abiAlignment(target);
|
||||
|
||||
if (isByRef(ret_ty)) {
|
||||
// operand is a pointer however self.ret_ptr is null so that means
|
||||
// we need to return a value.
|
||||
const casted_ptr = self.builder.buildBitCast(operand, ptr_abi_ty, "");
|
||||
const load_inst = self.builder.buildLoad(casted_ptr, "");
|
||||
load_inst.setAlignment(alignment);
|
||||
_ = self.builder.buildRet(load_inst);
|
||||
return null;
|
||||
}
|
||||
|
||||
const llvm_ret_ty = operand.typeOf();
|
||||
if (abi_ret_ty == llvm_ret_ty) {
|
||||
_ = self.builder.buildRet(operand);
|
||||
return null;
|
||||
}
|
||||
|
||||
const target = self.dg.module.getTarget();
|
||||
const alignment = ret_ty.abiAlignment(target);
|
||||
const ptr_abi_ty = abi_ret_ty.pointerType(0);
|
||||
const rp = self.buildAlloca(llvm_ret_ty);
|
||||
rp.setAlignment(alignment);
|
||||
const store_inst = self.builder.buildStore(operand, rp);
|
||||
|
||||
@ -169,6 +169,9 @@ pub const Value = opaque {
|
||||
pub const constNot = LLVMConstNot;
|
||||
extern fn LLVMConstNot(ConstantVal: *const Value) *const Value;
|
||||
|
||||
pub const constAdd = LLVMConstAdd;
|
||||
extern fn LLVMConstAdd(LHSConstant: *const Value, RHSConstant: *const Value) *const Value;
|
||||
|
||||
pub const setWeak = LLVMSetWeak;
|
||||
extern fn LLVMSetWeak(CmpXchgInst: *const Value, IsWeak: Bool) void;
|
||||
|
||||
|
||||
@ -408,3 +408,17 @@ test "function with inferred error set but returning no error" {
|
||||
const return_ty = @typeInfo(@TypeOf(S.foo)).Fn.return_type.?;
|
||||
try expectEqual(0, @typeInfo(@typeInfo(return_ty).ErrorUnion.error_set).ErrorSet.?.len);
|
||||
}
|
||||
|
||||
test "import passed byref to function in return type" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const S = struct {
|
||||
fn get() @import("std").ArrayListUnmanaged(i32) {
|
||||
var x: @import("std").ArrayListUnmanaged(i32) = .{};
|
||||
return x;
|
||||
}
|
||||
};
|
||||
var list = S.get();
|
||||
try expect(list.items.len == 0);
|
||||
}
|
||||
|
||||
@ -436,3 +436,25 @@ test "load pointer from packed struct" {
|
||||
try expect(i == 123);
|
||||
}
|
||||
}
|
||||
|
||||
test "@ptrToInt on a packed struct field" {
|
||||
if (builtin.zig_backend == .stage2_c) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_wasm) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest;
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest;
|
||||
|
||||
const S = struct {
|
||||
const P = packed struct {
|
||||
x: u8,
|
||||
y: u8,
|
||||
z: u32,
|
||||
};
|
||||
var p0: P = P{
|
||||
.x = 1,
|
||||
.y = 2,
|
||||
.z = 0,
|
||||
};
|
||||
};
|
||||
try expect(@ptrToInt(&S.p0.z) - @ptrToInt(&S.p0.x) == 2);
|
||||
}
|
||||
|
||||
@ -1226,3 +1226,33 @@ test "extern union most-aligned field is smaller" {
|
||||
var a: ?U = .{ .un = [_]u8{0} ** 110 };
|
||||
try expect(a != null);
|
||||
}
|
||||
|
||||
test "return an extern union from C calling convention" {
|
||||
if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
|
||||
if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
|
||||
|
||||
const namespace = struct {
|
||||
const S = extern struct {
|
||||
x: c_int,
|
||||
};
|
||||
const U = extern union {
|
||||
l: c_long,
|
||||
d: f64,
|
||||
s: S,
|
||||
};
|
||||
|
||||
fn bar(arg_u: U) callconv(.C) U {
|
||||
var u = arg_u;
|
||||
return u;
|
||||
}
|
||||
};
|
||||
|
||||
var u: namespace.U = namespace.U{
|
||||
.l = @as(c_long, 42),
|
||||
};
|
||||
u = namespace.bar(namespace.U{
|
||||
.d = 4.0,
|
||||
});
|
||||
try expect(u.d == 4.0);
|
||||
}
|
||||
|
||||
@ -891,39 +891,42 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
|
||||
\\}
|
||||
, "");
|
||||
|
||||
cases.add("Obscure ways of calling functions; issue #4124",
|
||||
\\#include <stdlib.h>
|
||||
\\static int add(int a, int b) {
|
||||
\\ return a + b;
|
||||
\\}
|
||||
\\typedef int (*adder)(int, int);
|
||||
\\typedef void (*funcptr)(void);
|
||||
\\int main() {
|
||||
\\ if ((add)(1, 2) != 3) abort();
|
||||
\\ if ((&add)(1, 2) != 3) abort();
|
||||
\\ if (add(3, 1) != 4) abort();
|
||||
\\ if ((*add)(2, 3) != 5) abort();
|
||||
\\ if ((**add)(7, -1) != 6) abort();
|
||||
\\ if ((***add)(-2, 9) != 7) abort();
|
||||
\\
|
||||
\\ int (*ptr)(int a, int b);
|
||||
\\ ptr = add;
|
||||
\\
|
||||
\\ if (ptr(1, 2) != 3) abort();
|
||||
\\ if ((*ptr)(3, 1) != 4) abort();
|
||||
\\ if ((**ptr)(2, 3) != 5) abort();
|
||||
\\ if ((***ptr)(7, -1) != 6) abort();
|
||||
\\ if ((****ptr)(-2, 9) != 7) abort();
|
||||
\\
|
||||
\\ funcptr addr1 = (funcptr)(add);
|
||||
\\ funcptr addr2 = (funcptr)(&add);
|
||||
\\
|
||||
\\ if (addr1 != addr2) abort();
|
||||
\\ if (((int(*)(int, int))addr1)(1, 2) != 3) abort();
|
||||
\\ if (((adder)addr2)(1, 2) != 3) abort();
|
||||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
if (@import("builtin").zig_backend == .stage1) {
|
||||
// https://github.com/ziglang/zig/issues/12263
|
||||
cases.add("Obscure ways of calling functions; issue #4124",
|
||||
\\#include <stdlib.h>
|
||||
\\static int add(int a, int b) {
|
||||
\\ return a + b;
|
||||
\\}
|
||||
\\typedef int (*adder)(int, int);
|
||||
\\typedef void (*funcptr)(void);
|
||||
\\int main() {
|
||||
\\ if ((add)(1, 2) != 3) abort();
|
||||
\\ if ((&add)(1, 2) != 3) abort();
|
||||
\\ if (add(3, 1) != 4) abort();
|
||||
\\ if ((*add)(2, 3) != 5) abort();
|
||||
\\ if ((**add)(7, -1) != 6) abort();
|
||||
\\ if ((***add)(-2, 9) != 7) abort();
|
||||
\\
|
||||
\\ int (*ptr)(int a, int b);
|
||||
\\ ptr = add;
|
||||
\\
|
||||
\\ if (ptr(1, 2) != 3) abort();
|
||||
\\ if ((*ptr)(3, 1) != 4) abort();
|
||||
\\ if ((**ptr)(2, 3) != 5) abort();
|
||||
\\ if ((***ptr)(7, -1) != 6) abort();
|
||||
\\ if ((****ptr)(-2, 9) != 7) abort();
|
||||
\\
|
||||
\\ funcptr addr1 = (funcptr)(add);
|
||||
\\ funcptr addr2 = (funcptr)(&add);
|
||||
\\
|
||||
\\ if (addr1 != addr2) abort();
|
||||
\\ if (((int(*)(int, int))addr1)(1, 2) != 3) abort();
|
||||
\\ if (((adder)addr2)(1, 2) != 3) abort();
|
||||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
}
|
||||
|
||||
cases.add("Return boolean expression as int; issue #6215",
|
||||
\\#include <stdlib.h>
|
||||
@ -1319,25 +1322,28 @@ pub fn addCases(cases: *tests.RunTranslatedCContext) void {
|
||||
\\}
|
||||
, "");
|
||||
|
||||
cases.add("basic vector expressions",
|
||||
\\#include <stdlib.h>
|
||||
\\#include <stdint.h>
|
||||
\\typedef int16_t __v8hi __attribute__((__vector_size__(16)));
|
||||
\\int main(int argc, char**argv) {
|
||||
\\ __v8hi uninitialized;
|
||||
\\ __v8hi empty_init = {};
|
||||
\\ __v8hi partial_init = {0, 1, 2, 3};
|
||||
\\
|
||||
\\ __v8hi a = {0, 1, 2, 3, 4, 5, 6, 7};
|
||||
\\ __v8hi b = (__v8hi) {100, 200, 300, 400, 500, 600, 700, 800};
|
||||
\\
|
||||
\\ __v8hi sum = a + b;
|
||||
\\ for (int i = 0; i < 8; i++) {
|
||||
\\ if (sum[i] != a[i] + b[i]) abort();
|
||||
\\ }
|
||||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
if (@import("builtin").zig_backend == .stage1) {
|
||||
// https://github.com/ziglang/zig/issues/12264
|
||||
cases.add("basic vector expressions",
|
||||
\\#include <stdlib.h>
|
||||
\\#include <stdint.h>
|
||||
\\typedef int16_t __v8hi __attribute__((__vector_size__(16)));
|
||||
\\int main(int argc, char**argv) {
|
||||
\\ __v8hi uninitialized;
|
||||
\\ __v8hi empty_init = {};
|
||||
\\ __v8hi partial_init = {0, 1, 2, 3};
|
||||
\\
|
||||
\\ __v8hi a = {0, 1, 2, 3, 4, 5, 6, 7};
|
||||
\\ __v8hi b = (__v8hi) {100, 200, 300, 400, 500, 600, 700, 800};
|
||||
\\
|
||||
\\ __v8hi sum = a + b;
|
||||
\\ for (int i = 0; i < 8; i++) {
|
||||
\\ if (sum[i] != a[i] + b[i]) abort();
|
||||
\\ }
|
||||
\\ return 0;
|
||||
\\}
|
||||
, "");
|
||||
}
|
||||
|
||||
cases.add("__builtin_shufflevector",
|
||||
\\#include <stdlib.h>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user