authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-19 23:24:33-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-11-21 20:43:41-05:00
logcf2fe2536e65e7d0d8892f630282f3d264454cc3
treed45185013737be416031b62a8bce1dfd4cc2f2c7
parent47f06be36943f808aa9798c19172363afe6ae35c
signaturelock-open Commit is signed but in an unrecognized format.

better error message when null termination does not match


2 files changed, 33 insertions(+), 7 deletions(-)

lib/std/c.zig+1-1
...@@ -63,7 +63,7 @@ pub extern "c" fn fclose(stream: *FILE) c_int;...@@ -63,7 +63,7 @@ pub extern "c" fn fclose(stream: *FILE) c_int;
63pub extern "c" fn fwrite(ptr: [*]const u8, size_of_type: usize, item_count: usize, stream: *FILE) usize;63pub extern "c" fn fwrite(ptr: [*]const u8, size_of_type: usize, item_count: usize, stream: *FILE) usize;
64pub extern "c" fn fread(ptr: [*]u8, size_of_type: usize, item_count: usize, stream: *FILE) usize;64pub extern "c" fn fread(ptr: [*]u8, size_of_type: usize, item_count: usize, stream: *FILE) usize;
6565
66pub extern "c" fn printf(format: [*]const u8, ...) c_int;66pub extern "c" fn printf(format: [*]null const u8, ...) c_int;
67pub extern "c" fn abort() noreturn;67pub extern "c" fn abort() noreturn;
68pub extern "c" fn exit(code: c_int) noreturn;68pub extern "c" fn exit(code: c_int) noreturn;
69pub extern "c" fn isatty(fd: fd_t) c_int;69pub extern "c" fn isatty(fd: fd_t) c_int;
src/ir.cpp+32-6
...@@ -68,6 +68,7 @@ enum ConstCastResultId {...@@ -68,6 +68,7 @@ enum ConstCastResultId {
68 ConstCastResultIdBadAllowsZero,68 ConstCastResultIdBadAllowsZero,
69 ConstCastResultIdArrayChild,69 ConstCastResultIdArrayChild,
70 ConstCastResultIdBadNullTermArrays,70 ConstCastResultIdBadNullTermArrays,
71 ConstCastResultIdPtrLens,
71};72};
7273
73struct ConstCastOnly;74struct ConstCastOnly;
...@@ -92,6 +93,7 @@ struct ConstCastTypeMismatch;...@@ -92,6 +93,7 @@ struct ConstCastTypeMismatch;
92struct ConstCastArrayMismatch;93struct ConstCastArrayMismatch;
93struct ConstCastBadAllowsZero;94struct ConstCastBadAllowsZero;
94struct ConstCastBadNullTermArrays;95struct ConstCastBadNullTermArrays;
96struct ConstCastBadPtrLens;
9597
96struct ConstCastOnly {98struct ConstCastOnly {
97 ConstCastResultId id;99 ConstCastResultId id;
...@@ -110,6 +112,7 @@ struct ConstCastOnly {...@@ -110,6 +112,7 @@ struct ConstCastOnly {
110 ConstCastArgNoAlias arg_no_alias;112 ConstCastArgNoAlias arg_no_alias;
111 ConstCastBadAllowsZero *bad_allows_zero;113 ConstCastBadAllowsZero *bad_allows_zero;
112 ConstCastBadNullTermArrays *bad_null_term_arrays;114 ConstCastBadNullTermArrays *bad_null_term_arrays;
115 ConstCastBadPtrLens *bad_ptr_lens;
113 } data;116 } data;
114};117};
115118
...@@ -169,6 +172,11 @@ struct ConstCastBadNullTermArrays {...@@ -169,6 +172,11 @@ struct ConstCastBadNullTermArrays {
169 ZigType *actual_type;172 ZigType *actual_type;
170};173};
171174
175struct ConstCastBadPtrLens {
176 ZigType *wanted_type;
177 ZigType *actual_type;
178};
179
172180
173static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);181static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);
174static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval,182static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *scope, LVal lval,
...@@ -9843,6 +9851,18 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted...@@ -9843,6 +9851,18 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
9843 bool actual_opt_or_ptr = actual_ptr_type != nullptr &&9851 bool actual_opt_or_ptr = actual_ptr_type != nullptr &&
9844 (actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional);9852 (actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional);
9845 if (wanted_opt_or_ptr && actual_opt_or_ptr) {9853 if (wanted_opt_or_ptr && actual_opt_or_ptr) {
9854 bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len;
9855 bool ok_null_term_ptrs =
9856 actual_ptr_type->data.pointer.ptr_len == PtrLenNull ||
9857 wanted_ptr_type->data.pointer.ptr_len == PtrLenUnknown;
9858 if (!(ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr || ok_null_term_ptrs)) {
9859 result.id = ConstCastResultIdPtrLens;
9860 result.data.bad_ptr_lens = allocate_nonzero<ConstCastBadPtrLens>(1);
9861 result.data.bad_ptr_lens->wanted_type = wanted_type;
9862 result.data.bad_ptr_lens->actual_type = actual_type;
9863 return result;
9864 }
9865
9846 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type,9866 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type,
9847 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const);9867 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const);
9848 if (child.id == ConstCastResultIdInvalid)9868 if (child.id == ConstCastResultIdInvalid)
...@@ -9881,12 +9901,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted...@@ -9881,12 +9901,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
9881 result.id = ConstCastResultIdInvalid;9901 result.id = ConstCastResultIdInvalid;
9882 return result;9902 return result;
9883 }9903 }
9884 bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len;9904 if (type_has_bits(wanted_type) == type_has_bits(actual_type) &&
9885 bool ok_null_term_ptrs =
9886 actual_ptr_type->data.pointer.ptr_len == PtrLenNull ||
9887 wanted_ptr_type->data.pointer.ptr_len == PtrLenUnknown;
9888 if ((ptr_lens_equal || wanted_is_c_ptr || actual_is_c_ptr || ok_null_term_ptrs) &&
9889 type_has_bits(wanted_type) == type_has_bits(actual_type) &&
9890 (!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) &&9905 (!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) &&
9891 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) &&9906 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) &&
9892 actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host &&9907 actual_ptr_type->data.pointer.bit_offset_in_host == wanted_ptr_type->data.pointer.bit_offset_in_host &&
...@@ -12569,6 +12584,17 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa...@@ -12569,6 +12584,17 @@ static void report_recursive_error(IrAnalyze *ira, AstNode *source_node, ConstCa
12569 }12584 }
12570 break;12585 break;
12571 }12586 }
12587 case ConstCastResultIdPtrLens: {
12588 ZigType *wanted_type = cast_result->data.bad_ptr_lens->wanted_type;
12589 ZigType *actual_type = cast_result->data.bad_ptr_lens->actual_type;
12590 bool wanted_null_term = wanted_type->data.pointer.ptr_len == PtrLenNull;
12591 bool actual_null_term = actual_type->data.pointer.ptr_len == PtrLenNull;
12592 if (wanted_null_term && !actual_null_term) {
12593 add_error_note(ira->codegen, parent_msg, source_node,
12594 buf_sprintf("destination type requires null termination"));
12595 }
12596 break;
12597 }
12572 case ConstCastResultIdFnIsGeneric:12598 case ConstCastResultIdFnIsGeneric:
12573 add_error_note(ira->codegen, parent_msg, source_node,12599 add_error_note(ira->codegen, parent_msg, source_node,
12574 buf_sprintf("only one of the functions is generic"));12600 buf_sprintf("only one of the functions is generic"));