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;
6363pub extern "c" fn fwrite(ptr: [*]const u8, size_of_type: usize, item_count: usize, stream: *FILE) usize;
6464pub 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;
6767pub extern "c" fn abort() noreturn;
6868pub extern "c" fn exit(code: c_int) noreturn;
6969pub extern "c" fn isatty(fd: fd_t) c_int;
src/ir.cpp+32-6
......@@ -68,6 +68,7 @@ enum ConstCastResultId {
6868 ConstCastResultIdBadAllowsZero,
6969 ConstCastResultIdArrayChild,
7070 ConstCastResultIdBadNullTermArrays,
71 ConstCastResultIdPtrLens,
7172};
7273
7374struct ConstCastOnly;
......@@ -92,6 +93,7 @@ struct ConstCastTypeMismatch;
9293struct ConstCastArrayMismatch;
9394struct ConstCastBadAllowsZero;
9495struct ConstCastBadNullTermArrays;
96struct ConstCastBadPtrLens;
9597
9698struct ConstCastOnly {
9799 ConstCastResultId id;
......@@ -110,6 +112,7 @@ struct ConstCastOnly {
110112 ConstCastArgNoAlias arg_no_alias;
111113 ConstCastBadAllowsZero *bad_allows_zero;
112114 ConstCastBadNullTermArrays *bad_null_term_arrays;
115 ConstCastBadPtrLens *bad_ptr_lens;
113116 } data;
114117};
115118
......@@ -169,6 +172,11 @@ struct ConstCastBadNullTermArrays {
169172 ZigType *actual_type;
170173};
171174
175struct ConstCastBadPtrLens {
176 ZigType *wanted_type;
177 ZigType *actual_type;
178};
179
172180
173181static IrInstruction *ir_gen_node(IrBuilder *irb, AstNode *node, Scope *scope);
174182static 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
98439851 bool actual_opt_or_ptr = actual_ptr_type != nullptr &&
98449852 (actual_type->id == ZigTypeIdPointer || actual_type->id == ZigTypeIdOptional);
98459853 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
98469866 ConstCastOnly child = types_match_const_cast_only(ira, wanted_ptr_type->data.pointer.child_type,
98479867 actual_ptr_type->data.pointer.child_type, source_node, !wanted_ptr_type->data.pointer.is_const);
98489868 if (child.id == ConstCastResultIdInvalid)
......@@ -9881,12 +9901,7 @@ static ConstCastOnly types_match_const_cast_only(IrAnalyze *ira, ZigType *wanted
98819901 result.id = ConstCastResultIdInvalid;
98829902 return result;
98839903 }
9884 bool ptr_lens_equal = actual_ptr_type->data.pointer.ptr_len == wanted_ptr_type->data.pointer.ptr_len;
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) &&
9904 if (type_has_bits(wanted_type) == type_has_bits(actual_type) &&
98909905 (!actual_ptr_type->data.pointer.is_const || wanted_ptr_type->data.pointer.is_const) &&
98919906 (!actual_ptr_type->data.pointer.is_volatile || wanted_ptr_type->data.pointer.is_volatile) &&
98929907 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
1256912584 }
1257012585 break;
1257112586 }
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 }
1257212598 case ConstCastResultIdFnIsGeneric:
1257312599 add_error_note(ira->codegen, parent_msg, source_node,
1257412600 buf_sprintf("only one of the functions is generic"));