diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2019-02-12 00:51:06 -0500 |
|---|---|---|
| committer | Andrew Kelley <andrew@ziglang.org> | 2019-02-12 00:51:06 -0500 |
| commit | 285e2f62ba0648d6d8e7ff64d1ee7d2900481e2f (patch) | |
| tree | ca99c7ae5e4e29bb12a750b92a8d292b3e09a556 | |
| parent | 0abe6d668eb52aefa59c75a8d8f782f2372f8600 (diff) | |
| download | zig-285e2f62ba0648d6d8e7ff64d1ee7d2900481e2f.tar.gz zig-285e2f62ba0648d6d8e7ff64d1ee7d2900481e2f.zip | |
disallow C pointers to non-C-ABI-compatible element types
See #1059
| -rw-r--r-- | src/analyze.cpp | 2 | ||||
| -rw-r--r-- | src/analyze.hpp | 2 | ||||
| -rw-r--r-- | src/ir.cpp | 4 | ||||
| -rw-r--r-- | test/compile_errors.zig | 10 |
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)); |
