From 92f1a29c4082817f11e12ff58bd4fdb5fffb8608 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Sun, 4 Dec 2022 15:03:32 +0200 Subject: [PATCH 1/8] AstGen: make `@compileError` operand implicitly comptime This matches the language reference. --- lib/std/build/OptionsStep.zig | 2 +- lib/std/fmt.zig | 2 +- lib/std/testing.zig | 2 +- src/AstGen.zig | 4 ++++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/std/build/OptionsStep.zig b/lib/std/build/OptionsStep.zig index 362aa64f33..0ac36bdffe 100644 --- a/lib/std/build/OptionsStep.zig +++ b/lib/std/build/OptionsStep.zig @@ -177,7 +177,7 @@ fn printLiteral(out: anytype, val: anytype, indent: u8) !void { .Float, .Null, => try out.print("{any}", .{val}), - else => @compileError(comptime std.fmt.comptimePrint("`{s}` are not yet supported as build options", .{@tagName(@typeInfo(T))})), + else => @compileError(std.fmt.comptimePrint("`{s}` are not yet supported as build options", .{@tagName(@typeInfo(T))})), } } diff --git a/lib/std/fmt.zig b/lib/std/fmt.zig index ae97b76124..903dd67c3d 100644 --- a/lib/std/fmt.zig +++ b/lib/std/fmt.zig @@ -199,7 +199,7 @@ pub fn format( switch (missing_count) { 0 => unreachable, 1 => @compileError("unused argument in '" ++ fmt ++ "'"), - else => @compileError((comptime comptimePrint("{d}", .{missing_count})) ++ " unused arguments in '" ++ fmt ++ "'"), + else => @compileError(comptimePrint("{d}", .{missing_count}) ++ " unused arguments in '" ++ fmt ++ "'"), } } } diff --git a/lib/std/testing.zig b/lib/std/testing.zig index 1bda46ecce..1a7d3fd732 100644 --- a/lib/std/testing.zig +++ b/lib/std/testing.zig @@ -765,7 +765,7 @@ pub fn checkAllAllocationFailures(backing_allocator: std.mem.Allocator, comptime } const expected_args_tuple_len = fn_args_fields.len - 1; if (extra_args.len != expected_args_tuple_len) { - @compileError("The provided function expects " ++ (comptime std.fmt.comptimePrint("{d}", .{expected_args_tuple_len})) ++ " extra arguments, but the provided tuple contains " ++ (comptime std.fmt.comptimePrint("{d}", .{extra_args.len}))); + @compileError("The provided function expects " ++ std.fmt.comptimePrint("{d}", .{expected_args_tuple_len}) ++ " extra arguments, but the provided tuple contains " ++ std.fmt.comptimePrint("{d}", .{extra_args.len})); } // Setup the tuple that will actually be used with @call (we'll need to insert diff --git a/src/AstGen.zig b/src/AstGen.zig index 4e571ffda9..c9f44a6216 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -8455,8 +8455,12 @@ fn simpleUnOp( operand_node: Ast.Node.Index, tag: Zir.Inst.Tag, ) InnerError!Zir.Inst.Ref { + const prev_force_comptime = gz.force_comptime; + defer gz.force_comptime = prev_force_comptime; + switch (tag) { .tag_name, .error_name, .ptr_to_int => try emitDbgNode(gz, node), + .compile_error => gz.force_comptime = true, else => {}, } const operand = try expr(gz, scope, operand_ri, operand_node); From d078d08e4f661c1b0bee31d7852e5e6058d54b11 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Mon, 5 Dec 2022 18:14:37 +0200 Subject: [PATCH 2/8] Sema: export function instead of the constant referencing it Closes #13706 --- src/Sema.zig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Sema.zig b/src/Sema.zig index 68348ac161..9f65a5117f 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -5405,6 +5405,13 @@ fn zirExport(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!void }, else => |e| return e, }; + { + try sema.mod.ensureDeclAnalyzed(decl_index); + const exported_decl = sema.mod.declPtr(decl_index); + if (exported_decl.val.castTag(.function)) |some| { + return sema.analyzeExport(block, src, options, some.data.owner_decl); + } + } try sema.analyzeExport(block, src, options, decl_index); } From ddce76059b1631f3eddc3c09615b26698210ba9e Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Mon, 5 Dec 2022 18:17:33 +0200 Subject: [PATCH 3/8] Sema: add error for `@tagName` on empty enum --- src/Sema.zig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Sema.zig b/src/Sema.zig index 9f65a5117f..50511bc57a 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -17877,6 +17877,13 @@ fn zirTagName(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!Air operand_ty.fmt(mod), }), }; + if (enum_ty.enumFieldCount() == 0) { + // TODO I don't think this is the correct way to handle this but + // it prevents a crash. + return sema.fail(block, operand_src, "cannot get @tagName of empty enum '{}'", .{ + enum_ty.fmt(mod), + }); + } const enum_decl_index = enum_ty.getOwnerDecl(); const casted_operand = try sema.coerce(block, enum_ty, operand, operand_src); if (try sema.resolveDefinedValue(block, operand_src, casted_operand)) |val| { From dff32a2cd73bf222b80ddc48c875fa0745288203 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Wed, 7 Dec 2022 14:48:10 +0200 Subject: [PATCH 4/8] Sema: resolve lazy values in analyzeMinMax Closes #13797 --- src/Sema.zig | 3 +++ test/behavior/maximum_minimum.zig | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/src/Sema.zig b/src/Sema.zig index 50511bc57a..3edc35aeb6 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -21011,6 +21011,9 @@ fn analyzeMinMax( if (rhs_val.isUndef()) return sema.addConstUndef(simd_op.result_ty); + try sema.resolveLazyValue(lhs_val); + try sema.resolveLazyValue(rhs_val); + const opFunc = switch (air_tag) { .min => Value.numberMin, .max => Value.numberMax, diff --git a/test/behavior/maximum_minimum.zig b/test/behavior/maximum_minimum.zig index 977d06204e..79ec5f14fa 100644 --- a/test/behavior/maximum_minimum.zig +++ b/test/behavior/maximum_minimum.zig @@ -95,3 +95,10 @@ test "@min for vectors" { try S.doTheTest(); comptime try S.doTheTest(); } + +test "@min/@max on lazy values" { + const A = extern struct { u8_4: [4]u8 }; + const B = extern struct { u8_16: [16]u8 }; + const size = @max(@sizeOf(A), @sizeOf(B)); + try expect(size == @sizeOf(B)); +} From 4fb9c75fc944bbc3242feff653aacd69e17b75dc Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Wed, 7 Dec 2022 14:54:29 +0200 Subject: [PATCH 5/8] compiler-rt: do not export complex arithmetic on ofmt=c These functions cannot be properly implemented without #8465 Closes #13800 --- lib/compiler_rt/divdc3.zig | 4 +++- lib/compiler_rt/divhc3.zig | 4 +++- lib/compiler_rt/divsc3.zig | 4 +++- lib/compiler_rt/divtc3.zig | 4 +++- lib/compiler_rt/divxc3.zig | 4 +++- lib/compiler_rt/muldc3.zig | 4 +++- lib/compiler_rt/mulhc3.zig | 4 +++- lib/compiler_rt/mulsc3.zig | 4 +++- lib/compiler_rt/multc3.zig | 4 +++- lib/compiler_rt/mulxc3.zig | 4 +++- 10 files changed, 30 insertions(+), 10 deletions(-) diff --git a/lib/compiler_rt/divdc3.zig b/lib/compiler_rt/divdc3.zig index f7592f639d..8aad682e61 100644 --- a/lib/compiler_rt/divdc3.zig +++ b/lib/compiler_rt/divdc3.zig @@ -3,7 +3,9 @@ const divc3 = @import("./divc3.zig"); const Complex = @import("./mulc3.zig").Complex; comptime { - @export(__divdc3, .{ .name = "__divdc3", .linkage = common.linkage }); + if (@import("builtin").zig_backend != .stage2_c) { + @export(__divdc3, .{ .name = "__divdc3", .linkage = common.linkage }); + } } pub fn __divdc3(a: f64, b: f64, c: f64, d: f64) callconv(.C) Complex(f64) { diff --git a/lib/compiler_rt/divhc3.zig b/lib/compiler_rt/divhc3.zig index e2d682fe2d..3de8967593 100644 --- a/lib/compiler_rt/divhc3.zig +++ b/lib/compiler_rt/divhc3.zig @@ -3,7 +3,9 @@ const divc3 = @import("./divc3.zig"); const Complex = @import("./mulc3.zig").Complex; comptime { - @export(__divhc3, .{ .name = "__divhc3", .linkage = common.linkage }); + if (@import("builtin").zig_backend != .stage2_c) { + @export(__divhc3, .{ .name = "__divhc3", .linkage = common.linkage }); + } } pub fn __divhc3(a: f16, b: f16, c: f16, d: f16) callconv(.C) Complex(f16) { diff --git a/lib/compiler_rt/divsc3.zig b/lib/compiler_rt/divsc3.zig index a64f14629c..c9e0c0cbf5 100644 --- a/lib/compiler_rt/divsc3.zig +++ b/lib/compiler_rt/divsc3.zig @@ -3,7 +3,9 @@ const divc3 = @import("./divc3.zig"); const Complex = @import("./mulc3.zig").Complex; comptime { - @export(__divsc3, .{ .name = "__divsc3", .linkage = common.linkage }); + if (@import("builtin").zig_backend != .stage2_c) { + @export(__divsc3, .{ .name = "__divsc3", .linkage = common.linkage }); + } } pub fn __divsc3(a: f32, b: f32, c: f32, d: f32) callconv(.C) Complex(f32) { diff --git a/lib/compiler_rt/divtc3.zig b/lib/compiler_rt/divtc3.zig index 190df5c067..e2382a1372 100644 --- a/lib/compiler_rt/divtc3.zig +++ b/lib/compiler_rt/divtc3.zig @@ -3,7 +3,9 @@ const divc3 = @import("./divc3.zig"); const Complex = @import("./mulc3.zig").Complex; comptime { - @export(__divtc3, .{ .name = "__divtc3", .linkage = common.linkage }); + if (@import("builtin").zig_backend != .stage2_c) { + @export(__divtc3, .{ .name = "__divtc3", .linkage = common.linkage }); + } } pub fn __divtc3(a: f128, b: f128, c: f128, d: f128) callconv(.C) Complex(f128) { diff --git a/lib/compiler_rt/divxc3.zig b/lib/compiler_rt/divxc3.zig index 32fb269ca5..c6ed5a210c 100644 --- a/lib/compiler_rt/divxc3.zig +++ b/lib/compiler_rt/divxc3.zig @@ -3,7 +3,9 @@ const divc3 = @import("./divc3.zig"); const Complex = @import("./mulc3.zig").Complex; comptime { - @export(__divxc3, .{ .name = "__divxc3", .linkage = common.linkage }); + if (@import("builtin").zig_backend != .stage2_c) { + @export(__divxc3, .{ .name = "__divxc3", .linkage = common.linkage }); + } } pub fn __divxc3(a: f80, b: f80, c: f80, d: f80) callconv(.C) Complex(f80) { diff --git a/lib/compiler_rt/muldc3.zig b/lib/compiler_rt/muldc3.zig index 343ae5a064..cef8f660b2 100644 --- a/lib/compiler_rt/muldc3.zig +++ b/lib/compiler_rt/muldc3.zig @@ -4,7 +4,9 @@ const mulc3 = @import("./mulc3.zig"); pub const panic = common.panic; comptime { - @export(__muldc3, .{ .name = "__muldc3", .linkage = common.linkage }); + if (@import("builtin").zig_backend != .stage2_c) { + @export(__muldc3, .{ .name = "__muldc3", .linkage = common.linkage }); + } } pub fn __muldc3(a: f64, b: f64, c: f64, d: f64) callconv(.C) mulc3.Complex(f64) { diff --git a/lib/compiler_rt/mulhc3.zig b/lib/compiler_rt/mulhc3.zig index f1fad90aff..70c68e2a72 100644 --- a/lib/compiler_rt/mulhc3.zig +++ b/lib/compiler_rt/mulhc3.zig @@ -4,7 +4,9 @@ const mulc3 = @import("./mulc3.zig"); pub const panic = common.panic; comptime { - @export(__mulhc3, .{ .name = "__mulhc3", .linkage = common.linkage }); + if (@import("builtin").zig_backend != .stage2_c) { + @export(__mulhc3, .{ .name = "__mulhc3", .linkage = common.linkage }); + } } pub fn __mulhc3(a: f16, b: f16, c: f16, d: f16) callconv(.C) mulc3.Complex(f16) { diff --git a/lib/compiler_rt/mulsc3.zig b/lib/compiler_rt/mulsc3.zig index 3ea055f9ff..5fe289453b 100644 --- a/lib/compiler_rt/mulsc3.zig +++ b/lib/compiler_rt/mulsc3.zig @@ -4,7 +4,9 @@ const mulc3 = @import("./mulc3.zig"); pub const panic = common.panic; comptime { - @export(__mulsc3, .{ .name = "__mulsc3", .linkage = common.linkage }); + if (@import("builtin").zig_backend != .stage2_c) { + @export(__mulsc3, .{ .name = "__mulsc3", .linkage = common.linkage }); + } } pub fn __mulsc3(a: f32, b: f32, c: f32, d: f32) callconv(.C) mulc3.Complex(f32) { diff --git a/lib/compiler_rt/multc3.zig b/lib/compiler_rt/multc3.zig index c6afcdefb2..94f2205d76 100644 --- a/lib/compiler_rt/multc3.zig +++ b/lib/compiler_rt/multc3.zig @@ -4,7 +4,9 @@ const mulc3 = @import("./mulc3.zig"); pub const panic = common.panic; comptime { - @export(__multc3, .{ .name = "__multc3", .linkage = common.linkage }); + if (@import("builtin").zig_backend != .stage2_c) { + @export(__multc3, .{ .name = "__multc3", .linkage = common.linkage }); + } } pub fn __multc3(a: f128, b: f128, c: f128, d: f128) callconv(.C) mulc3.Complex(f128) { diff --git a/lib/compiler_rt/mulxc3.zig b/lib/compiler_rt/mulxc3.zig index decba868e8..4a90d0e453 100644 --- a/lib/compiler_rt/mulxc3.zig +++ b/lib/compiler_rt/mulxc3.zig @@ -4,7 +4,9 @@ const mulc3 = @import("./mulc3.zig"); pub const panic = common.panic; comptime { - @export(__mulxc3, .{ .name = "__mulxc3", .linkage = common.linkage }); + if (@import("builtin").zig_backend != .stage2_c) { + @export(__mulxc3, .{ .name = "__mulxc3", .linkage = common.linkage }); + } } pub fn __mulxc3(a: f80, b: f80, c: f80, d: f80) callconv(.C) mulc3.Complex(f80) { From f8dcd3477541aabf3bfb05a1d2c51fa3797c0b48 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Wed, 7 Dec 2022 15:05:55 +0200 Subject: [PATCH 6/8] TypedValue.print: detect string literals Closes #4281 Closes #13785 --- src/TypedValue.zig | 50 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/src/TypedValue.zig b/src/TypedValue.zig index 619fb003f9..10ab88b866 100644 --- a/src/TypedValue.zig +++ b/src/TypedValue.zig @@ -46,6 +46,7 @@ pub fn enumToInt(tv: TypedValue, buffer: *Value.Payload.U64) Value { } const max_aggregate_items = 100; +const max_string_len = 256; const FormatContext = struct { tv: TypedValue, @@ -141,10 +142,12 @@ pub fn print( .extern_options_type => return writer.writeAll("std.builtin.ExternOptions"), .type_info_type => return writer.writeAll("std.builtin.Type"), - .empty_struct_value, .aggregate => { + .empty_struct_value => return writer.writeAll(".{}"), + .aggregate => { if (level == 0) { return writer.writeAll(".{ ... }"); } + const values = val.castTag(.aggregate).?; if (ty.zigTypeTag() == .Struct) { try writer.writeAll(".{"); const max_len = std.math.min(ty.structFieldCount(), max_aggregate_items); @@ -159,9 +162,9 @@ pub fn print( try print(.{ .ty = ty.structFieldType(i), .val = switch (ty.containerLayout()) { - .Packed => val.castTag(.aggregate).?.data[i], + .Packed => values.data[i], else => ty.structFieldValueComptime(i) orelse b: { - const vals = val.castTag(.aggregate).?.data; + const vals = values.data; break :b vals[i]; }, }, @@ -172,17 +175,31 @@ pub fn print( } return writer.writeAll("}"); } else { - try writer.writeAll(".{ "); const elem_ty = ty.elemType2(); const len = ty.arrayLen(); - const max_len = std.math.min(len, max_aggregate_items); + if (elem_ty.eql(Type.u8, mod)) str: { + const max_len = @intCast(usize, std.math.min(len, max_string_len)); + var buf: [max_string_len]u8 = undefined; + + var i: u32 = 0; + while (i < max_len) : (i += 1) { + buf[i] = std.math.cast(u8, values.data[i].toUnsignedInt(target)) orelse break :str; + } + + const truncated = if (len > max_string_len) " (truncated)" else ""; + return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated }); + } + + try writer.writeAll(".{ "); + + const max_len = std.math.min(len, max_aggregate_items); var i: u32 = 0; while (i < max_len) : (i += 1) { if (i != 0) try writer.writeAll(", "); try print(.{ .ty = elem_ty, - .val = val.castTag(.aggregate).?.data[i], + .val = values.data[i], }, writer, level - 1, mod); } if (len > max_aggregate_items) { @@ -372,11 +389,28 @@ pub fn print( return writer.writeAll(".{ ... }"); } const payload = val.castTag(.slice).?.data; - try writer.writeAll(".{ "); const elem_ty = ty.elemType2(); const len = payload.len.toUnsignedInt(target); - const max_len = std.math.min(len, max_aggregate_items); + if (elem_ty.eql(Type.u8, mod)) str: { + const max_len = @intCast(usize, std.math.min(len, max_string_len)); + var buf: [max_string_len]u8 = undefined; + + var i: u32 = 0; + while (i < max_len) : (i += 1) { + var elem_buf: Value.ElemValueBuffer = undefined; + const elem_val = payload.ptr.elemValueBuffer(mod, i, &elem_buf); + buf[i] = std.math.cast(u8, elem_val.toUnsignedInt(target)) orelse break :str; + } + + // TODO would be nice if this had a bit of unicode awareness. + const truncated = if (len > max_string_len) " (truncated)" else ""; + return writer.print("\"{}{s}\"", .{ std.zig.fmtEscapes(buf[0..max_len]), truncated }); + } + + try writer.writeAll(".{ "); + + const max_len = std.math.min(len, max_aggregate_items); var i: u32 = 0; while (i < max_len) : (i += 1) { if (i != 0) try writer.writeAll(", "); From 653c0bae0c473c52716dad35ec8f7f9511114a56 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Wed, 7 Dec 2022 15:30:18 +0200 Subject: [PATCH 7/8] remove stage1 specific compile error tests --- ...attempt_to_use_0_bit_type_in_extern_fn.zig | 17 ------------ .../comptime_ptrcast_of_zero-sized_type.zig | 12 --------- ...uality_but_sets_have_no_common_members.zig | 16 ----------- ...ing_undefined_c_pointer_to_zig_pointer.zig | 11 -------- ..._from_undefined_array_pointer_to_slice.zig | 27 ------------------- .../stage1/ptrToInt_on_void.zig | 9 ------- ...rToInt_with_pointer_to_zero-sized_type.zig | 11 -------- ...ype.Pointer_with_invalid_address_space.zig | 18 ------------- ...eify_type_with_non-constant_expression.zig | 11 -------- .../slicing_of_global_undefined_pointer.zig | 10 ------- ...itch_with_invalid_expression_parameter.zig | 17 ------------ ...omptime-known_undefined_function_value.zig | 13 --------- 12 files changed, 172 deletions(-) delete mode 100644 test/cases/compile_errors/stage1/attempt_to_use_0_bit_type_in_extern_fn.zig delete mode 100644 test/cases/compile_errors/stage1/comptime_ptrcast_of_zero-sized_type.zig delete mode 100644 test/cases/compile_errors/stage1/error_equality_but_sets_have_no_common_members.zig delete mode 100644 test/cases/compile_errors/stage1/implicit_casting_undefined_c_pointer_to_zig_pointer.zig delete mode 100644 test/cases/compile_errors/stage1/issue_2687_coerce_from_undefined_array_pointer_to_slice.zig delete mode 100644 test/cases/compile_errors/stage1/ptrToInt_on_void.zig delete mode 100644 test/cases/compile_errors/stage1/ptrToInt_with_pointer_to_zero-sized_type.zig delete mode 100644 test/cases/compile_errors/stage1/reify_type.Pointer_with_invalid_address_space.zig delete mode 100644 test/cases/compile_errors/stage1/reify_type_with_non-constant_expression.zig delete mode 100644 test/cases/compile_errors/stage1/slicing_of_global_undefined_pointer.zig delete mode 100644 test/cases/compile_errors/stage1/switch_with_invalid_expression_parameter.zig delete mode 100644 test/cases/compile_errors/stage1/use_of_comptime-known_undefined_function_value.zig diff --git a/test/cases/compile_errors/stage1/attempt_to_use_0_bit_type_in_extern_fn.zig b/test/cases/compile_errors/stage1/attempt_to_use_0_bit_type_in_extern_fn.zig deleted file mode 100644 index 021cd97f19..0000000000 --- a/test/cases/compile_errors/stage1/attempt_to_use_0_bit_type_in_extern_fn.zig +++ /dev/null @@ -1,17 +0,0 @@ -extern fn foo(ptr: fn(*void) callconv(.C) void) void; - -export fn entry() void { - foo(bar); -} - -fn bar(x: *void) callconv(.C) void { _ = x; } -export fn entry2() void { - bar(&{}); -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:1:23: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C' -// tmp.zig:7:11: error: parameter of type '*void' has 0 bits; not allowed in function with calling convention 'C' diff --git a/test/cases/compile_errors/stage1/comptime_ptrcast_of_zero-sized_type.zig b/test/cases/compile_errors/stage1/comptime_ptrcast_of_zero-sized_type.zig deleted file mode 100644 index 231e735cfa..0000000000 --- a/test/cases/compile_errors/stage1/comptime_ptrcast_of_zero-sized_type.zig +++ /dev/null @@ -1,12 +0,0 @@ -fn foo() void { - const node: struct {} = undefined; - const vla_ptr = @ptrCast([*]const u8, &node); - _ = vla_ptr; -} -comptime { foo(); } - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:21: error: '*const struct:2:17' and '[*]const u8' do not have the same in-memory representation diff --git a/test/cases/compile_errors/stage1/error_equality_but_sets_have_no_common_members.zig b/test/cases/compile_errors/stage1/error_equality_but_sets_have_no_common_members.zig deleted file mode 100644 index d42169b503..0000000000 --- a/test/cases/compile_errors/stage1/error_equality_but_sets_have_no_common_members.zig +++ /dev/null @@ -1,16 +0,0 @@ -const Set1 = error{A, C}; -const Set2 = error{B, D}; -export fn entry() void { - foo(Set1.A); -} -fn foo(x: Set1) void { - if (x == Set2.B) { - - } -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:7:11: error: error sets 'Set1' and 'Set2' have no common errors diff --git a/test/cases/compile_errors/stage1/implicit_casting_undefined_c_pointer_to_zig_pointer.zig b/test/cases/compile_errors/stage1/implicit_casting_undefined_c_pointer_to_zig_pointer.zig deleted file mode 100644 index 5554146fa5..0000000000 --- a/test/cases/compile_errors/stage1/implicit_casting_undefined_c_pointer_to_zig_pointer.zig +++ /dev/null @@ -1,11 +0,0 @@ -comptime { - var c_ptr: [*c]u8 = undefined; - var zig_ptr: *u8 = c_ptr; - _ = zig_ptr; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:24: error: use of undefined value here causes undefined behavior diff --git a/test/cases/compile_errors/stage1/issue_2687_coerce_from_undefined_array_pointer_to_slice.zig b/test/cases/compile_errors/stage1/issue_2687_coerce_from_undefined_array_pointer_to_slice.zig deleted file mode 100644 index 21fbb6b4fe..0000000000 --- a/test/cases/compile_errors/stage1/issue_2687_coerce_from_undefined_array_pointer_to_slice.zig +++ /dev/null @@ -1,27 +0,0 @@ -export fn foo1() void { - const a: *[1]u8 = undefined; - var b: []u8 = a; - _ = b; -} -export fn foo2() void { - comptime { - var a: *[1]u8 = undefined; - var b: []u8 = a; - _ = b; - } -} -export fn foo3() void { - comptime { - const a: *[1]u8 = undefined; - var b: []u8 = a; - _ = b; - } -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:19: error: use of undefined value here causes undefined behavior -// tmp.zig:9:23: error: use of undefined value here causes undefined behavior -// tmp.zig:16:23: error: use of undefined value here causes undefined behavior diff --git a/test/cases/compile_errors/stage1/ptrToInt_on_void.zig b/test/cases/compile_errors/stage1/ptrToInt_on_void.zig deleted file mode 100644 index 5012be65e0..0000000000 --- a/test/cases/compile_errors/stage1/ptrToInt_on_void.zig +++ /dev/null @@ -1,9 +0,0 @@ -export fn entry() bool { - return @ptrToInt(&{}) == @ptrToInt(&{}); -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:23: error: pointer to size 0 type has no address diff --git a/test/cases/compile_errors/stage1/ptrToInt_with_pointer_to_zero-sized_type.zig b/test/cases/compile_errors/stage1/ptrToInt_with_pointer_to_zero-sized_type.zig deleted file mode 100644 index 143dc9135d..0000000000 --- a/test/cases/compile_errors/stage1/ptrToInt_with_pointer_to_zero-sized_type.zig +++ /dev/null @@ -1,11 +0,0 @@ -export fn entry() void { - var pointer: ?*u0 = null; - var x = @ptrToInt(pointer); - _ = x; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:23: error: pointer to size 0 type has no address diff --git a/test/cases/compile_errors/stage1/reify_type.Pointer_with_invalid_address_space.zig b/test/cases/compile_errors/stage1/reify_type.Pointer_with_invalid_address_space.zig deleted file mode 100644 index 1ca97ce250..0000000000 --- a/test/cases/compile_errors/stage1/reify_type.Pointer_with_invalid_address_space.zig +++ /dev/null @@ -1,18 +0,0 @@ -export fn entry() void { - _ = @Type(.{ .Pointer = .{ - .size = .One, - .is_const = false, - .is_volatile = false, - .alignment = 1, - .address_space = .gs, - .child = u8, - .is_allowzero = false, - .sentinel = null, - }}); -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:2:16: error: address space 'gs' not available in stage 1 compiler, must be .generic diff --git a/test/cases/compile_errors/stage1/reify_type_with_non-constant_expression.zig b/test/cases/compile_errors/stage1/reify_type_with_non-constant_expression.zig deleted file mode 100644 index 7eec6b395a..0000000000 --- a/test/cases/compile_errors/stage1/reify_type_with_non-constant_expression.zig +++ /dev/null @@ -1,11 +0,0 @@ -const builtin = @import("std").builtin; -var globalTypeInfo : builtin.Type = undefined; -export fn entry() void { - _ = @Type(globalTypeInfo); -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:4:15: error: unable to evaluate constant expression diff --git a/test/cases/compile_errors/stage1/slicing_of_global_undefined_pointer.zig b/test/cases/compile_errors/stage1/slicing_of_global_undefined_pointer.zig deleted file mode 100644 index 8bbc0f85eb..0000000000 --- a/test/cases/compile_errors/stage1/slicing_of_global_undefined_pointer.zig +++ /dev/null @@ -1,10 +0,0 @@ -var buf: *[1]u8 = undefined; -export fn entry() void { - _ = buf[0..1]; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:3:12: error: non-zero length slice of undefined pointer diff --git a/test/cases/compile_errors/stage1/switch_with_invalid_expression_parameter.zig b/test/cases/compile_errors/stage1/switch_with_invalid_expression_parameter.zig deleted file mode 100644 index 1eb74519f5..0000000000 --- a/test/cases/compile_errors/stage1/switch_with_invalid_expression_parameter.zig +++ /dev/null @@ -1,17 +0,0 @@ -export fn entry() void { - Test(i32); -} -fn Test(comptime T: type) void { - const x = switch (T) { - []u8 => |x| x, - i32 => |x| x, - else => unreachable, - }; - _ = x; -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:7:17: error: switch on type 'type' provides no expression parameter diff --git a/test/cases/compile_errors/stage1/use_of_comptime-known_undefined_function_value.zig b/test/cases/compile_errors/stage1/use_of_comptime-known_undefined_function_value.zig deleted file mode 100644 index 3500b13dfc..0000000000 --- a/test/cases/compile_errors/stage1/use_of_comptime-known_undefined_function_value.zig +++ /dev/null @@ -1,13 +0,0 @@ -const Cmd = struct { - exec: fn () void, -}; -export fn entry() void { - const command = Cmd{ .exec = undefined }; - command.exec(); -} - -// error -// backend=stage1 -// target=native -// -// tmp.zig:6:12: error: use of undefined value here causes undefined behavior From 6039554b26b1aee6502063d9130907369c4ffd38 Mon Sep 17 00:00:00 2001 From: Veikka Tuominen Date: Wed, 7 Dec 2022 21:43:01 +0200 Subject: [PATCH 8/8] tokenizer: detect null bytes before EOF Closes #13811 --- lib/std/zig/tokenizer.zig | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/std/zig/tokenizer.zig b/lib/std/zig/tokenizer.zig index d322b98f71..93f0339c41 100644 --- a/lib/std/zig/tokenizer.zig +++ b/lib/std/zig/tokenizer.zig @@ -425,7 +425,16 @@ pub const Tokenizer = struct { const c = self.buffer[self.index]; switch (state) { .start => switch (c) { - 0 => break, + 0 => { + if (self.index != self.buffer.len) { + result.tag = .invalid; + result.loc.start = self.index; + self.index += 1; + result.loc.end = self.index; + return result; + } + break; + }, ' ', '\n', '\t', '\r' => { result.loc.start = self.index + 1; }, @@ -1851,6 +1860,13 @@ test "saturating operators" { try testTokenize("-|=", &.{.minus_pipe_equal}); } +test "null byte before eof" { + try testTokenize("123 \x00 456", &.{ .number_literal, .invalid, .number_literal }); + try testTokenize("//\x00", &.{.invalid}); + try testTokenize("\\\\\x00", &.{ .multiline_string_literal_line, .invalid }); + try testTokenize("\x00", &.{.invalid}); +} + fn testTokenize(source: [:0]const u8, expected_token_tags: []const Token.Tag) !void { var tokenizer = Tokenizer.init(source); for (expected_token_tags) |expected_token_tag| {