aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2019-02-12 00:51:06 -0500
committerAndrew Kelley <andrew@ziglang.org>2019-02-12 00:51:06 -0500
commit285e2f62ba0648d6d8e7ff64d1ee7d2900481e2f (patch)
treeca99c7ae5e4e29bb12a750b92a8d292b3e09a556
parent0abe6d668eb52aefa59c75a8d8f782f2372f8600 (diff)
downloadzig-285e2f62ba0648d6d8e7ff64d1ee7d2900481e2f.tar.gz
zig-285e2f62ba0648d6d8e7ff64d1ee7d2900481e2f.zip
disallow C pointers to non-C-ABI-compatible element types
See #1059
-rw-r--r--src/analyze.cpp2
-rw-r--r--src/analyze.hpp2
-rw-r--r--src/ir.cpp4
-rw-r--r--test/compile_errors.zig10
4 files changed, 16 insertions, 2 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index af6200cc82..ab2afba561 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -1469,7 +1469,7 @@ static bool type_allowed_in_packed_struct(ZigType *type_entry) {
zig_unreachable();
}
-static bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {
+bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry) {
switch (type_entry->id) {
case ZigTypeIdInvalid:
zig_unreachable();
diff --git a/src/analyze.hpp b/src/analyze.hpp
index 1e4f2f2ce7..c8141b02ff 100644
--- a/src/analyze.hpp
+++ b/src/analyze.hpp
@@ -44,7 +44,7 @@ void find_libc_include_path(CodeGen *g);
void find_libc_lib_path(CodeGen *g);
bool type_has_bits(ZigType *type_entry);
-
+bool type_allowed_in_extern(CodeGen *g, ZigType *type_entry);
ImportTableEntry *add_source_file(CodeGen *g, PackageTableEntry *package, Buf *abs_full_path, Buf *source_code);
diff --git a/src/ir.cpp b/src/ir.cpp
index 1f0edc910d..64e08ef7ea 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -21145,6 +21145,10 @@ static IrInstruction *ir_analyze_instruction_ptr_type(IrAnalyze *ira, IrInstruct
} else if (child_type->id == ZigTypeIdOpaque && instruction->ptr_len == PtrLenUnknown) {
ir_add_error(ira, &instruction->base, buf_sprintf("unknown-length pointer to opaque"));
return ira->codegen->invalid_instruction;
+ } else if (instruction->ptr_len == PtrLenC && !type_allowed_in_extern(ira->codegen, child_type)) {
+ ir_add_error(ira, &instruction->base,
+ buf_sprintf("C pointers cannot point to non-C-ABI-compatible type '%s'", buf_ptr(&child_type->name)));
+ return ira->codegen->invalid_instruction;
}
uint32_t align_bytes;
diff --git a/test/compile_errors.zig b/test/compile_errors.zig
index b47cdf2ed1..63850bb888 100644
--- a/test/compile_errors.zig
+++ b/test/compile_errors.zig
@@ -2,6 +2,16 @@ const tests = @import("tests.zig");
pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.addTest(
+ "C pointer pointing to non C ABI compatible type",
+ \\const Foo = struct {};
+ \\export fn entry() [*c]Foo {
+ \\ return undefined;
+ \\}
+ ,
+ ".tmp_source.zig:2:19: error: C pointers cannot point to non-C-ABI-compatible type 'Foo'",
+ );
+
+ cases.addTest(
"@truncate undefined value",
\\export fn entry() void {
\\ var z = @truncate(u8, u16(undefined));