Skip to content

stage1: add a compile error for using @bitCast to convert an enum to an integer #10269

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions lib/std/special/compiler_rt/compareXf2.zig
Original file line number Diff line number Diff line change
Expand Up @@ -89,13 +89,13 @@ pub inline fn unordcmp(comptime T: type, a: T, b: T) i32 {
pub fn __lesf2(a: f32, b: f32) callconv(.C) i32 {
@setRuntimeSafety(builtin.is_test);
const float = cmp(f32, LE, a, b);
return @bitCast(i32, float);
return @enumToInt(float);
}

pub fn __gesf2(a: f32, b: f32) callconv(.C) i32 {
@setRuntimeSafety(builtin.is_test);
const float = cmp(f32, GE, a, b);
return @bitCast(i32, float);
return @enumToInt(float);
}

pub fn __eqsf2(a: f32, b: f32) callconv(.C) i32 {
Expand All @@ -119,13 +119,13 @@ pub fn __gtsf2(a: f32, b: f32) callconv(.C) i32 {
pub fn __ledf2(a: f64, b: f64) callconv(.C) i32 {
@setRuntimeSafety(builtin.is_test);
const float = cmp(f64, LE, a, b);
return @bitCast(i32, float);
return @enumToInt(float);
}

pub fn __gedf2(a: f64, b: f64) callconv(.C) i32 {
@setRuntimeSafety(builtin.is_test);
const float = cmp(f64, GE, a, b);
return @bitCast(i32, float);
return @enumToInt(float);
}

pub fn __eqdf2(a: f64, b: f64) callconv(.C) i32 {
Expand All @@ -149,13 +149,13 @@ pub fn __gtdf2(a: f64, b: f64) callconv(.C) i32 {
pub fn __letf2(a: f128, b: f128) callconv(.C) i32 {
@setRuntimeSafety(builtin.is_test);
const float = cmp(f128, LE, a, b);
return @bitCast(i32, float);
return @enumToInt(float);
}

pub fn __getf2(a: f128, b: f128) callconv(.C) i32 {
@setRuntimeSafety(builtin.is_test);
const float = cmp(f128, GE, a, b);
return @bitCast(i32, float);
return @enumToInt(float);
}

pub fn __eqtf2(a: f128, b: f128) callconv(.C) i32 {
Expand Down
6 changes: 6 additions & 0 deletions src/stage1/ir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12110,6 +12110,12 @@ static Stage1AirInst *ir_resolve_result_raw(IrAnalyze *ira, Stage1ZirInst *suspe
return ira->codegen->invalid_inst_gen;
}

if (value_type->id == ZigTypeIdEnum && dest_type->id == ZigTypeIdInt) {
ir_add_error_node(ira, suspend_source_instr->source_node,
buf_sprintf("@bitCast used instead of @enumToInt to convert an enum to an integer"));
return ira->codegen->invalid_inst_gen;
}

Stage1AirInst *bitcasted_value;
if (value != nullptr) {
bitcasted_value = ir_analyze_bit_cast(ira, result_loc->source_instruction->scope,
Expand Down
16 changes: 0 additions & 16 deletions test/behavior/bitcast.zig
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,6 @@ test "nested bitcast" {
comptime try S.foo(42);
}

test "@bitCast enum to its integer type" {
const SOCK = enum(c_int) {
A,
B,

fn testBitCastExternEnum() !void {
var SOCK_DGRAM = @This().B;
var sock_dgram = @bitCast(c_int, SOCK_DGRAM);
try expect(sock_dgram == 1);
}
};

try SOCK.testBitCastExternEnum();
comptime try SOCK.testBitCastExternEnum();
}

// issue #3010: compiler segfault
test "bitcast literal [4]u8 param to u32" {
const ip = @bitCast(u32, [_]u8{ 255, 255, 255, 255 });
Expand Down
11 changes: 11 additions & 0 deletions test/compile_errors.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1496,6 +1496,17 @@ pub fn addCases(ctx: *TestContext) !void {
"tmp.zig:2:24: error: cannot cast a value of type 'y'",
});

ctx.objErrStage1("bitCast enum to integer type",
\\export fn entry() void {
\\ const Number = enum(u32) { one, two };
\\ const x: Number = .one;
\\ const y = @bitCast(u32, x);
\\ _ = y;
\\}
, &[_][]const u8{
"tmp.zig:4:29: error: @bitCast used instead of @enumToInt to convert an enum to an integer",
});

ctx.objErrStage1("comparing against undefined produces undefined value",
\\export fn entry() void {
\\ if (2 == undefined) {}
Expand Down