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 362aa64f33a603f3151ad5803c9ac2c01333f9ce..0ac36bdffe4f0468c2d2925ed2ada06b59583793 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 ae97b76124c6133266696440fe597c8f45d83371..903dd67c3d9f88a7b6961ec1adbf7425d5f2c0e4 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 1bda46ecce69e18dcd558852b915cb9c3911b0c1..1a7d3fd73210631018e70bef7afbc6685849a3cf 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 4e571ffda9cf5d5f80e55ee08b2ac57296a5d00a..c9f44a62161375093cbfd40678570f89993dc119 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); -- 2.54.0 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 68348ac161cfa02fbbdf595494431447c8d885be..9f65a5117f5e9dffb40418ac640ff18cbc1513f2 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); } -- 2.54.0 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 9f65a5117f5e9dffb40418ac640ff18cbc1513f2..50511bc57a5ae143388de4529a290599df7bdfa5 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| { -- 2.54.0 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 50511bc57a5ae143388de4529a290599df7bdfa5..3edc35aeb65c82c19c4d09f4a80175ea2817c892 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 977d06204e43de5d2c323508db3de579d563e446..79ec5f14fa802c207f727897e23f5c20f839c123 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)); +} -- 2.54.0 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 f7592f639d371038f81ebcad5fd961a32d38e9d9..8aad682e6196f86799884c09a2352006415d0f6c 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 e2d682fe2deeb600c473a6ac559cb87f9a431602..3de89675933247966e6b5c991e504da2907b36e2 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 a64f14629c9d4dd8390e8066f54d4e2a4fd1cfee..c9e0c0cbf567e14179958030cdd0999e9548c0d7 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 190df5c06773d1fa12dd1818cbe5ba1086fa5374..e2382a1372beac68b9d57f637ea2da72d9d7c383 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 32fb269ca5f32c3cd828819cdef160e5256a81de..c6ed5a210c6e653b5467f7bf7cd6bba098a867e4 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 343ae5a064a9fdadc10be14f70cb72e9fb825c36..cef8f660b20486b5a5b6aa4ae06184511a6eabe1 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 f1fad90affbaf45dcfd89f63204112d96e1fd483..70c68e2a72d0ecf03340b7a694865fd38ef179d2 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 3ea055f9fffd2b39806855a5424adda65b5a5331..5fe289453b385ddcec56101b9de940b2cdad2296 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 c6afcdefb2eef7709c386222202fa4dc68b8c4c5..94f2205d7658361f2e37bd1e07c47cfdb1edbb10 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 decba868e8dc03a081078228a41cd6193e7a8164..4a90d0e45306d93637cad24952e5a3d41236f076 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) { -- 2.54.0 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 619fb003f9a6ebc0b62574aa0d1873a65479fe37..10ab88b86622f31ffcc0996b6dbcb62c42e56fd7 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(); + + 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); + + 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(", "); -- 2.54.0 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 021cd97f190493043b72f1aa12338e5c4b5b2cc2..0000000000000000000000000000000000000000 --- 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 231e735cfa4d58e356123505bb6c8f7134146963..0000000000000000000000000000000000000000 --- 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 d42169b5036f40ba0725358de24a370d58b85bc9..0000000000000000000000000000000000000000 --- 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 5554146fa57dd3278dcb1ed933220dd098bf9943..0000000000000000000000000000000000000000 --- 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 21fbb6b4fe94a065781e911e13b83359e0125bb4..0000000000000000000000000000000000000000 --- 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 5012be65e076eb0a161fe8e90515df84d17231ca..0000000000000000000000000000000000000000 --- 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 143dc9135d435bbb32aed09820d56961366accd3..0000000000000000000000000000000000000000 --- 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 1ca97ce2505eba7d621ace7737485dc70434c79e..0000000000000000000000000000000000000000 --- 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 7eec6b395a81a8972f70c6d6295821bc72d510f4..0000000000000000000000000000000000000000 --- 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 8bbc0f85ebb7a4249e54f56f16b0710d02004705..0000000000000000000000000000000000000000 --- 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 1eb74519f50fb197b25a5bf4fc843b3c83b3c52b..0000000000000000000000000000000000000000 --- 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 3500b13dfc21df3fa6fe0eab59da94cf47884da7..0000000000000000000000000000000000000000 --- 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 -- 2.54.0 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 d322b98f71f4293f8225088d6d62920bac0a2626..93f0339c41a44e0f9c4c9dae189a86f82eb4d5e5 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| { -- 2.54.0