authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-01-06 19:54:14+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-01-06 19:36:17-05:00
log8c640b3e604e597ba49abbda39bd97c379072a3a
treeab0aedc4572504248d61a074faa31637444b0ae9
parent7e7d0e1ffaaee4f3deb49d3b98ffd5fcefaf85b1

Prevent bitCast to enum types

Stop the user from creating invalid enum values.

2 files changed, 18 insertions(+), 5 deletions(-)

src/ir.cpp+8-1
...@@ -27078,13 +27078,20 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_...@@ -27078,13 +27078,20 @@ static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_
27078 ir_assert(get_codegen_ptr_type(dest_type) == nullptr, source_instr);27078 ir_assert(get_codegen_ptr_type(dest_type) == nullptr, source_instr);
27079 ir_assert(type_can_bit_cast(dest_type), source_instr);27079 ir_assert(type_can_bit_cast(dest_type), source_instr);
2708027080
27081 if (dest_type->id == ZigTypeIdEnum) {
27082 ErrorMsg *msg = ir_add_error_node(ira, source_instr->source_node,
27083 buf_sprintf("cannot cast a value of type '%s'", buf_ptr(&dest_type->name)));
27084 add_error_note(ira->codegen, msg, source_instr->source_node,
27085 buf_sprintf("use @intToEnum for type coercion"));
27086 return ira->codegen->invalid_instruction;
27087 }
27088
27081 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusSizeKnown)))27089 if ((err = type_resolve(ira->codegen, dest_type, ResolveStatusSizeKnown)))
27082 return ira->codegen->invalid_instruction;27090 return ira->codegen->invalid_instruction;
2708327091
27084 if ((err = type_resolve(ira->codegen, src_type, ResolveStatusSizeKnown)))27092 if ((err = type_resolve(ira->codegen, src_type, ResolveStatusSizeKnown)))
27085 return ira->codegen->invalid_instruction;27093 return ira->codegen->invalid_instruction;
2708627094
27087
27088 uint64_t dest_size_bytes = type_size(ira->codegen, dest_type);27095 uint64_t dest_size_bytes = type_size(ira->codegen, dest_type);
27089 uint64_t src_size_bytes = type_size(ira->codegen, src_type);27096 uint64_t src_size_bytes = type_size(ira->codegen, src_type);
27090 if (dest_size_bytes != src_size_bytes) {27097 if (dest_size_bytes != src_size_bytes) {
test/compile_errors.zig+10-4
...@@ -2,6 +2,14 @@ const tests = @import("tests.zig");...@@ -2,6 +2,14 @@ const tests = @import("tests.zig");
2const builtin = @import("builtin");2const builtin = @import("builtin");
33
4pub fn addCases(cases: *tests.CompileErrorContext) void {4pub fn addCases(cases: *tests.CompileErrorContext) void {
5 cases.add("bitCast to enum type",
6 \\export fn entry() void {
7 \\ const y = @bitCast(enum(u32) { a, b }, @as(u32, 3));
8 \\}
9 , &[_][]const u8{
10 "tmp.zig:2:24: error: cannot cast a value of type 'y'",
11 });
12
5 cases.add("comparing against undefined produces undefined value",13 cases.add("comparing against undefined produces undefined value",
6 \\export fn entry() void {14 \\export fn entry() void {
7 \\ if (2 == undefined) {}15 \\ if (2 == undefined) {}
...@@ -31,8 +39,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -31,8 +39,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
31 "tmp.zig:3:12: note: destination pointer requires a terminating '0' sentinel",39 "tmp.zig:3:12: note: destination pointer requires a terminating '0' sentinel",
32 });40 });
3341
34 cases.add(42 cases.add("cmpxchg with float",
35 "cmpxchg with float",
36 \\export fn entry() void {43 \\export fn entry() void {
37 \\ var x: f32 = 0;44 \\ var x: f32 = 0;
38 \\ _ = @cmpxchgWeak(f32, &x, 1, 2, .SeqCst, .SeqCst);45 \\ _ = @cmpxchgWeak(f32, &x, 1, 2, .SeqCst, .SeqCst);
...@@ -41,8 +48,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {...@@ -41,8 +48,7 @@ pub fn addCases(cases: *tests.CompileErrorContext) void {
41 "tmp.zig:3:22: error: expected integer, enum or pointer type, found 'f32'",48 "tmp.zig:3:22: error: expected integer, enum or pointer type, found 'f32'",
42 });49 });
4350
44 cases.add(51 cases.add("atomicrmw with float op not .Xchg, .Add or .Sub",
45 "atomicrmw with float op not .Xchg, .Add or .Sub",
46 \\export fn entry() void {52 \\export fn entry() void {
47 \\ var x: f32 = 0;53 \\ var x: f32 = 0;
48 \\ _ = @atomicRmw(f32, &x, .And, 2, .SeqCst);54 \\ _ = @atomicRmw(f32, &x, .And, 2, .SeqCst);