Skip to content
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

Multiple external function declarations causes compiler segfault #529

Closed
snocl opened this Issue Oct 9, 2017 · 2 comments

Comments

Projects
None yet
2 participants
@snocl
Copy link
Contributor

commented Oct 9, 2017

Trying to reference an extern function declared with two different types causes the compiler to segfault, even when the types should be “compatible”.

This is a problem if multiple parts of a code base (say, two different statically linked libraries) try to use the same external function, but ends up using different argument types, e.g., through different instances of extern struct.

Example

Sources:

// main.zig

const A = extern struct {
    field: c_int,
};

extern "c" fn f(?*A) void;

pub fn main() void {
    _ = @import("other.zig").f;
    _ = f;
}
// other.zig

pub const A = extern struct {
    field: c_int,
};

pub extern "c" fn f(?*A) void;

Note that main.A and other.A are distinct types; by replacing both definitions with const A = c_int; the example compiles.

Build command:

$ zig build-exe main.zig
    OR
$ zig build-obj main.zig

Back trace:

* thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=1, address=0x6661656c2d86)
  * frame #0: 0x00000001021b89c1 zig`llvm::AttributeList::addAttributes(llvm::LLVMContext&, unsigned int, llvm::AttrBuilder const&) const + 91
    frame #1: 0x00000001021b8c01 zig`llvm::AttributeList::addAttribute(llvm::LLVMContext&, unsigned int, llvm::Attribute) const + 93
    frame #2: 0x000000010220e177 zig`llvm::Function::addAttribute(unsigned int, llvm::Attribute) + 41
    frame #3: 0x000000010002da9a zig`addLLVMAttr(val=0x000000010722bed8, attr_index=4294967295, attr_name="nounwind") at codegen.cpp:282
    frame #4: 0x000000010002ef74 zig`addLLVMFnAttr(fn_val=0x000000010722bed8, attr_name="nounwind") at codegen.cpp:303
    frame #5: 0x000000010002d8f5 zig`fn_llvm_value(g=0x0000000105017000, fn_table_entry=0x000000010669fa90) at codegen.cpp:462
    frame #6: 0x000000010002628f zig`do_code_gen(g=0x0000000105017000) at codegen.cpp:4222
    frame #7: 0x0000000100025771 zig`codegen_build(g=0x0000000105017000) at codegen.cpp:5562
    frame #8: 0x000000010008f723 zig`main(argc=3, argv=0x00007fff5fbff7c0) at main.cpp:788
    frame #9: 0x00007fffac045235 libdyld.dylib`start + 1

It looks like the problem occurs because the extern functions instead of being referenced through their local declarations, get referenced through a global table in:

https://github.com/zig-lang/zig/blob/5931a6b1a5b8f4941fc9b78f8960745f81594f17/src/codegen.cpp#L362-L368

The invalid cast on line 365 then seems to be what causes the crash later.

@andrewrk andrewrk added the bug label Oct 9, 2017

@andrewrk andrewrk added this to the 0.1.0 milestone Oct 9, 2017

@andrewrk

This comment has been minimized.

Copy link
Member

commented Oct 9, 2017

Strange, that bitcast is supposed to make exactly this situation work correctly. I'll look into this.

@andrewrk andrewrk modified the milestones: 0.1.0, 0.2.0 Oct 16, 2017

andrewrk added a commit that referenced this issue Nov 10, 2017

@andrewrk

This comment has been minimized.

Copy link
Member

commented Nov 10, 2017

I think this issue is fixed but I'm going to leave it open until I add a unit test for it.

@andrewrk andrewrk modified the milestones: 0.2.0, 0.3.0 Mar 15, 2018

@andrewrk andrewrk modified the milestones: 0.3.0, 0.4.0 Sep 3, 2018

@andrewrk andrewrk closed this in 557983e Feb 27, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.