Closed
Description
Zig Version
0.10.0-dev.2577+5816d3eae
Steps to Reproduce
Based on the discussion on #11887
I was trying to make my C interop code use anyopaque
to represent C's void *
.
To be quite honest, at this point I don't really understand what's going on, and am just trying to make the types match.
This is my Zig code (file src/encoder_test_void.zig
):
const std = @import("std");
const tst = std.testing;
const c = @cImport({
@cInclude("gl_void.c");
@cInclude("search.h");
});
fn strToPtr(str: [:0]const u8) *const anyopaque {
// we cast the `[*:0]const u8` multi-item pointer to `*const anyopaque`
// and don't keep the length from the slice
return @ptrCast(*const anyopaque, str.ptr);
}
fn ptrToStr(ptr: ?*anyopaque) [:0]u8 {
// in order to reconstruct the slice we use `std.mem.span` which uses
// the fact it is zero terminated to basically `strlen` it
return std.mem.span(@ptrCast([*:0]u8, ptr));
}
fn zigStore(key: [:0]const u8, value: [:0]const u8) void {
c.store(key, strToPtr(value));
}
fn zigFetch(key: [:0]const u8) ?[:0]u8 {
const Result = struct {
var value: ?*anyopaque = undefined;
};
const found = c.fetch(key, &Result.value);
return if (found == 0) null else ptrToStr(Result.value);
}
test "can store data in hash table" {
try tst.expectEqual(@as(i32, 1), c.hcreate(10));
try tst.expectEqual(@as(?[:0]u8, null), zigFetch("foo"));
try tst.expectEqual(@as(?[:0]u8, null), zigFetch("bar"));
zigStore("foo", "foo-value");
try tst.expectEqual(@as(?[:0]const u8, "foo-value"), zigFetch("foo"));
try tst.expectEqual(@as(?[:0]u8, null), zigFetch("bar"));
zigStore("bar", "bar-value");
try tst.expectEqual(@as(?[:0]const u8, "foo-value"), zigFetch("foo"));
try tst.expectEqual(@as(?[:0]const u8, "bar-value"), zigFetch("bar"));
}
The C code this is importing (file c/gl_void.c
):
#include <inttypes.h> /* intptr_t, PRIxPTR */
#include <search.h> /* hcreate(), hsearch() */
#include <stdio.h> /* perror(), printf() */
#include <stdlib.h> /* exit() */
void fail(const char *message)
{
perror(message);
exit(1);
}
/*
* Must hcreate() the hash table before calling fetch() or store().
*
* Because p->data is a pointer, fetch() and store() cast between
* void * and intptr_t.
*/
/* Fetch value from the hash table. */
int fetch(const char *key, void **value)
{
ENTRY e = {.key = (char *)key}, *p;
p = hsearch(e, FIND);
if (p) {
*value = (void *) p->data;
return 1;
} else
return 0;
}
/* Store key-value pair into the hash table. */
void store(const char *key, const void *value)
{
/*
* hsearch() may insert a new entry or find an existing entry
* with the same key. hsearch() ignores e.data if it finds an
* existing entry. We must call hsearch(), then set p->data.
*/
ENTRY e = {.key = (char *)key}, *p;
p = hsearch(e, ENTER);
if (p == NULL)
fail("hsearch store failed");
p->data = (void *) value;
}
Run with:
zig test src/encoder_test_void.zig -I c
As far as I can tell, the C code actually works, though I wouldn't be surprised if it's full of undefined behaviour. It's based on this: http://rosettacode.org/wiki/Associative_arrays/Creation/C#POSIX_hsearch.28.29
Expected Behavior
I expected my Zig tests to pass.
Actual Behavior
I get a compiler error saying this is a bug in the Zig compiler:
▶ zig test src/encoder_test_void.zig -I c
broken LLVM module found: Call parameter type does not match function signature!
%7 = alloca %"?[:0]u8", align 8
%"?[:0]const u8"* %25 = call fastcc i16 @std.testing.expectEqual.32(%std.builtin.StackTrace* %0, %"?[:0]const u8"* bitcast ({ %"[]u8", i1, [7 x i8] }* @90 to %"?[:0]const u8"*), %"?[:0]u8"* %7), !dbg !1724
Call parameter type does not match function signature!
%11 = alloca %"?[:0]u8", align 8
%"?[:0]const u8"* %31 = call fastcc i16 @std.testing.expectEqual.32(%std.builtin.StackTrace* %0, %"?[:0]const u8"* bitcast ({ %"[]u8", i1, [7 x i8] }* @97 to %"?[:0]const u8"*), %"?[:0]u8"* %11), !dbg !1731
Call parameter type does not match function signature!
%13 = alloca %"?[:0]u8", align 8
%"?[:0]const u8"* %34 = call fastcc i16 @std.testing.expectEqual.32(%std.builtin.StackTrace* %0, %"?[:0]const u8"* bitcast ({ %"[]u8", i1, [7 x i8] }* @99 to %"?[:0]const u8"*), %"?[:0]u8"* %13), !dbg !1734
This is a bug in the Zig compiler.thread 5510346 panic:
Unable to dump stack trace: debug info stripped
[1] 29193 abort zig test src/encoder_test_void.zig -I c