comptime detection of casting null to pointer

See #1059
This commit is contained in:
Andrew Kelley 2019-02-14 00:40:39 -05:00
parent 5699ab5e77
commit d4d2718bca
No known key found for this signature in database
GPG Key ID: 7C5F548F728501A9
2 changed files with 34 additions and 3 deletions

View File

@ -20645,12 +20645,23 @@ static IrInstruction *ir_analyze_ptr_cast(IrAnalyze *ira, IrInstruction *source_
}
if (instr_is_comptime(ptr)) {
// Undefined is OK here; @ptrCast is defined to reinterpret the bit pattern
// of the pointer as the new pointer type.
ConstExprValue *val = ir_resolve_const(ira, ptr, UndefOk);
bool dest_allows_addr_zero = ptr_allows_addr_zero(dest_type);
UndefAllowed is_undef_allowed = dest_allows_addr_zero ? UndefOk : UndefBad;
ConstExprValue *val = ir_resolve_const(ira, ptr, is_undef_allowed);
if (!val)
return ira->codegen->invalid_instruction;
if (val->special == ConstValSpecialStatic) {
bool is_addr_zero = val->data.x_ptr.special == ConstPtrSpecialNull ||
(val->data.x_ptr.special == ConstPtrSpecialHardCodedAddr &&
val->data.x_ptr.data.hard_coded_addr.addr == 0);
if (is_addr_zero && !dest_allows_addr_zero) {
ir_add_error(ira, source_instr,
buf_sprintf("null pointer casted to type '%s'", buf_ptr(&dest_type->name)));
return ira->codegen->invalid_instruction;
}
}
IrInstruction *result = ir_const(ira, source_instr, dest_type);
copy_const_val(&result->value, val, false);
result->value.type = dest_type;

View File

@ -1,6 +1,26 @@
const tests = @import("tests.zig");
pub fn addCases(cases: *tests.CompileErrorContext) void {
cases.addTest(
"implicit casting null c pointer to zig pointer",
\\comptime {
\\ var c_ptr: [*c]u8 = 0;
\\ var zig_ptr: *u8 = c_ptr;
\\}
,
".tmp_source.zig:3:24: error: null pointer casted to type '*u8'",
);
cases.addTest(
"implicit casting undefined c pointer to zig pointer",
\\comptime {
\\ var c_ptr: [*c]u8 = undefined;
\\ var zig_ptr: *u8 = c_ptr;
\\}
,
".tmp_source.zig:3:24: error: use of undefined value here causes undefined behavior",
);
cases.addTest(
"implicit casting C pointers which would mess up null semantics",
\\export fn entry() void {