zig/test/behavior/bugs/9584.zig
Andrew Kelley 6d6cf59847 stage2: support nested structs and arrays and sret
* Add AIR instructions: ret_ptr, ret_load
   - This allows Sema to be blissfully unaware of the backend's decision
     to implement by-val/by-ref semantics for struct/union/array types.
     Backends can lower these simply as alloc, load, ret instructions,
     or they can take advantage of them to use a result pointer.
 * Add AIR instruction: array_elem_val
   - Allows for better codegen for `Sema.elemVal`.
 * Implement calculation of ABI alignment and ABI size for unions.
 * Before appending the following AIR instructions to a block,
   resolveTypeLayout is called on the type:
   - call - return type
   - ret - return type
   - store_ptr - elem type
 * Sema: fix memory leak in `zirArrayInit` and other cleanups to this
   function.
 * x86_64: implement the full x86_64 C ABI according to the spec
 * Type: implement `intInfo` for error sets.
 * Type: implement `intTagType` for tagged unions.

The Zig type tag `Fn` is now used exclusively for function bodies.
Function pointers are modeled as `*const T` where `T` is a `Fn` type.
 * The `call` AIR instruction now allows a function pointer operand as
   well as a function operand.
 * Sema now has a coercion from function body to function pointer.
 * Function type syntax, e.g. `fn()void`, now returns zig tag type of
   Pointer with child Fn, rather than Fn directly.
   - I think this should probably be reverted. Will discuss the lang
     specs before doing this. Idea being that function pointers would
     need to be specified as `*const fn()void` rather than `fn() void`.

LLVM backend:
 * Enable calling the panic handler (previously this just
   emitted `@breakpoint()` since the backend could not handle the panic
   function).
 * Implement sret
 * Introduce `isByRef` and implement it for structs and arrays. Types
   that are `isByRef` are now passed as pointers to functions, and e.g.
   `elem_val` will return a pointer instead of doing a load.
 * Move the function type creating code from `resolveLlvmFunction` to
   `llvmType` where it belongs; now there is only 1 instance of this
   logic instead of two.
 * Add the `nonnull` attribute to non-optional pointer parameters.
 * Fix `resolveGlobalDecl` not using fully-qualified names and not using
   the `decl_map`.
 * Implement `genTypedValue` for pointer-like optionals.
 * Fix memory leak when lowering `block` instruction and OOM occurs.
 * Implement volatile checks where relevant.
2021-10-11 11:39:12 -07:00

62 lines
983 B
Zig

const std = @import("std");
const A = packed struct {
a: bool,
b: bool,
c: bool,
d: bool,
e: bool,
f: bool,
g: bool,
h: bool,
};
const X = union {
x: A,
y: u64,
};
pub fn a(
x0: i32,
x1: i32,
x2: i32,
x3: i32,
x4: i32,
flag_a: bool,
flag_b: bool,
) !void {
_ = x0;
_ = x1;
_ = x2;
_ = x3;
_ = x4;
_ = flag_a;
// With this bug present, `flag_b` would actually contain the value 17.
// Note: this bug only presents itself on debug mode.
try std.testing.expect(@ptrCast(*const u8, &flag_b).* == 1);
}
pub fn b(x: *X) !void {
try a(0, 1, 2, 3, 4, x.x.a, x.x.b);
}
test "bug 9584" {
var flags = A{
.a = false,
.b = true,
.c = false,
.d = false,
.e = false,
.f = true,
.g = false,
.h = false,
};
var x = X{
.x = flags,
};
try b(&x);
comptime if (@sizeOf(A) != 1) unreachable;
}