New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Setting derefed pointer to packed struct member generates invalid llvm #1121

Closed
Hejsil opened this Issue Jun 15, 2018 · 2 comments

Comments

Projects
None yet
2 participants
@Hejsil
Member

Hejsil commented Jun 15, 2018

I'm not on current master, but I'm pretty sure this hasn't been fixed.
Zig version: 0.2.0.b11c5d8f

const S = packed struct {
    a: u2,
    b: u2,
};

test "" {
    var s = S{.a = 2, .b = 0};
    var b_ptr = &s.b;
    b_ptr.* = 2;
}
Stored value type does not match pointer operand type!
  store i8* %2, i2** %b_ptr, align 8, !dbg !642
 i2*LLVM ERROR: Broken module found, compilation aborted!

@andrewrk andrewrk added this to the 0.3.0 milestone Jun 15, 2018

@andrewrk andrewrk added the bug label Jun 15, 2018

@Hejsil Hejsil changed the title from Setting deferred pointer to packed struct member generates invalid llvm to Setting derefed pointer to packed struct member generates invalid llvm Jun 18, 2018

@andrewrk

This comment has been minimized.

Member

andrewrk commented Jun 20, 2018

I think I need to rework the bit field pointer metadata.

Right now the type of b_ptr is *align(1:2:4) u2:

  • The pointer address points to the containing integer, which in this case zig has selected a u8 to contain the u2 fields.
  • First number (1) is byte alignment of the pointer address.
  • Second number (2) is the bit offset in the containing integer. The problem is that we don't know the size of the containing integer from the pointer metadata so we cannot use this information.
  • Third number (4) is the end bit offset in the containing integer. This information is redundant with the child element type (u2).

So I think to fix this we will have to change it to: *align(1:2:1) u2. This will be the same as before, except the third number is replaced with the byte count of the containing integer that can be found at the pointer's address. So then when zig dereferences this pointer, it knows to load a 1 byte integer, then shift right to offset by 2, and then mask to get only 2 bits.

andrewrk added a commit that referenced this issue Sep 26, 2018

@andrewrk andrewrk closed this in 589201b Sep 26, 2018

@andrewrk andrewrk added the breaking label Sep 26, 2018

@andrewrk

This comment has been minimized.

Member

andrewrk commented Sep 26, 2018

I implemented the above described change, and now the issue is fixed. In the unlikely scenario that you have explicitly align(x:y:z) in your code, the meaning of z is changed as described above.

emekoi added a commit to emekoi/zig that referenced this issue Sep 27, 2018

emekoi added a commit to emekoi/zig that referenced this issue Sep 27, 2018

emekoi added a commit to emekoi/zig that referenced this issue Sep 27, 2018

emekoi added a commit to emekoi/zig that referenced this issue Sep 27, 2018

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment