aboutsummaryrefslogtreecommitdiff
path: root/src/ir.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2019-02-14 00:40:39 -0500
committerAndrew Kelley <andrew@ziglang.org>2019-02-14 00:40:39 -0500
commitd4d2718bca9e23ceec029bb505c0ea1b91c875b6 (patch)
treec2b7b61f36fff694f5ff030fde50846b23c690cd /src/ir.cpp
parent5699ab5e77f8d13cac1e34775e6e51358119965c (diff)
downloadzig-d4d2718bca9e23ceec029bb505c0ea1b91c875b6.tar.gz
zig-d4d2718bca9e23ceec029bb505c0ea1b91c875b6.zip
comptime detection of casting null to pointer
See #1059
Diffstat (limited to 'src/ir.cpp')
-rw-r--r--src/ir.cpp17
1 files changed, 14 insertions, 3 deletions
diff --git a/src/ir.cpp b/src/ir.cpp
index 19bec193d5..f064adb128 100644
--- a/src/ir.cpp
+++ b/src/ir.cpp
@@ -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;