diff --git a/doc/langref.html.in b/doc/langref.html.in index e4b318929d..4307dd72e6 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -8041,7 +8041,7 @@ pub const CallModifier = enum { {#header_close#} {#header_open|@cDefine#} -
{#syntax#}@cDefine(comptime name: []u8, value) void{#endsyntax#}
+ {#syntax#}@cDefine(comptime name: []const u8, value) void{#endsyntax#}
This function can only occur inside {#syntax#}@cImport{#endsyntax#}.
@@ -8085,7 +8085,7 @@ pub const CallModifier = enum { {#see_also|Import from C Header File|@cInclude|@cDefine|@cUndef#} {#header_close#} {#header_open|@cInclude#} -{#syntax#}@cInclude(comptime path: []u8) void{#endsyntax#}
+ {#syntax#}@cInclude(comptime path: []const u8) void{#endsyntax#}
This function can only occur inside {#syntax#}@cImport{#endsyntax#}.
@@ -8176,7 +8176,7 @@ fn cmpxchgWeakButNotAtomic(comptime T: type, ptr: *T, expected_value: T, new_val {#header_close#} {#header_open|@compileError#} -{#syntax#}@compileError(comptime msg: []u8) noreturn{#endsyntax#}
+ {#syntax#}@compileError(comptime msg: []const u8) noreturn{#endsyntax#}
This function, when semantically analyzed, causes a compile error with the message {#syntax#}msg{#endsyntax#}. @@ -8267,7 +8267,7 @@ test "main" { {#header_close#} {#header_open|@cUndef#} -
{#syntax#}@cUndef(comptime name: []u8) void{#endsyntax#}
+ {#syntax#}@cUndef(comptime name: []const u8) void{#endsyntax#}
This function can only occur inside {#syntax#}@cImport{#endsyntax#}.
@@ -8607,7 +8607,7 @@ test "@hasDecl" { {#header_close#} {#header_open|@import#} -{#syntax#}@import(comptime path: []u8) type{#endsyntax#}
+ {#syntax#}@import(comptime path: []const u8) type{#endsyntax#}
This function finds a zig file corresponding to {#syntax#}path{#endsyntax#} and adds it to the build, if it is not already added. diff --git a/src/AstGen.zig b/src/AstGen.zig index 1aa70d86a9..0a82f59082 100644 --- a/src/AstGen.zig +++ b/src/AstGen.zig @@ -2456,45 +2456,45 @@ fn blockExprStmts(gz: *GenZir, parent_scope: *Scope, statements: []const Ast.Nod while (true) { switch (node_tags[inner_node]) { // zig fmt: off - .global_var_decl, - .local_var_decl, - .simple_var_decl, - .aligned_var_decl, => scope = try varDecl(gz, scope, statement, block_arena_allocator, tree.fullVarDecl(statement).?), + .global_var_decl, + .local_var_decl, + .simple_var_decl, + .aligned_var_decl, => scope = try varDecl(gz, scope, statement, block_arena_allocator, tree.fullVarDecl(statement).?), - .@"defer" => scope = try deferStmt(gz, scope, statement, block_arena_allocator, .defer_normal), - .@"errdefer" => scope = try deferStmt(gz, scope, statement, block_arena_allocator, .defer_error), + .@"defer" => scope = try deferStmt(gz, scope, statement, block_arena_allocator, .defer_normal), + .@"errdefer" => scope = try deferStmt(gz, scope, statement, block_arena_allocator, .defer_error), - .assign => try assign(gz, scope, statement), + .assign => try assign(gz, scope, statement), - .assign_shl => try assignShift(gz, scope, statement, .shl), - .assign_shr => try assignShift(gz, scope, statement, .shr), + .assign_shl => try assignShift(gz, scope, statement, .shl), + .assign_shr => try assignShift(gz, scope, statement, .shr), - .assign_bit_and => try assignOp(gz, scope, statement, .bit_and), - .assign_bit_or => try assignOp(gz, scope, statement, .bit_or), - .assign_bit_xor => try assignOp(gz, scope, statement, .xor), - .assign_div => try assignOp(gz, scope, statement, .div), - .assign_sub => try assignOp(gz, scope, statement, .sub), - .assign_sub_wrap => try assignOp(gz, scope, statement, .subwrap), - .assign_mod => try assignOp(gz, scope, statement, .mod_rem), - .assign_add => try assignOp(gz, scope, statement, .add), - .assign_add_wrap => try assignOp(gz, scope, statement, .addwrap), - .assign_mul => try assignOp(gz, scope, statement, .mul), - .assign_mul_wrap => try assignOp(gz, scope, statement, .mulwrap), + .assign_bit_and => try assignOp(gz, scope, statement, .bit_and), + .assign_bit_or => try assignOp(gz, scope, statement, .bit_or), + .assign_bit_xor => try assignOp(gz, scope, statement, .xor), + .assign_div => try assignOp(gz, scope, statement, .div), + .assign_sub => try assignOp(gz, scope, statement, .sub), + .assign_sub_wrap => try assignOp(gz, scope, statement, .subwrap), + .assign_mod => try assignOp(gz, scope, statement, .mod_rem), + .assign_add => try assignOp(gz, scope, statement, .add), + .assign_add_wrap => try assignOp(gz, scope, statement, .addwrap), + .assign_mul => try assignOp(gz, scope, statement, .mul), + .assign_mul_wrap => try assignOp(gz, scope, statement, .mulwrap), - .grouped_expression => { - inner_node = node_data[statement].lhs; - continue; - }, + .grouped_expression => { + inner_node = node_data[statement].lhs; + continue; + }, - .while_simple, - .while_cont, - .@"while", => _ = try whileExpr(gz, scope, .{ .rl = .none }, inner_node, tree.fullWhile(inner_node).?, true), + .while_simple, + .while_cont, + .@"while", => _ = try whileExpr(gz, scope, .{ .rl = .none }, inner_node, tree.fullWhile(inner_node).?, true), - .for_simple, - .@"for", => _ = try forExpr(gz, scope, .{ .rl = .none }, inner_node, tree.fullFor(inner_node).?, true), + .for_simple, + .@"for", => _ = try forExpr(gz, scope, .{ .rl = .none }, inner_node, tree.fullFor(inner_node).?, true), - else => noreturn_src_node = try unusedResultExpr(gz, scope, inner_node), - // zig fmt: on + else => noreturn_src_node = try unusedResultExpr(gz, scope, inner_node), + // zig fmt: on } break; } @@ -8428,11 +8428,11 @@ fn builtinCall( .bit_size_of => return simpleUnOpType(gz, scope, ri, node, params[0], .bit_size_of), .align_of => return simpleUnOpType(gz, scope, ri, node, params[0], .align_of), - .int_from_ptr => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .int_from_ptr), + .int_from_ptr => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .int_from_ptr), .compile_error => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .slice_const_u8_type } }, params[0], .compile_error), .set_eval_branch_quota => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .coerced_ty = .u32_type } }, params[0], .set_eval_branch_quota), - .int_from_enum => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .int_from_enum), - .int_from_bool => return simpleUnOp(gz, scope, ri, node, bool_ri, params[0], .int_from_bool), + .int_from_enum => return simpleUnOp(gz, scope, ri, node, .{ .rl = .none }, params[0], .int_from_enum), + .int_from_bool => return simpleUnOp(gz, scope, ri, node, bool_ri, params[0], .int_from_bool), .embed_file => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .slice_const_u8_type } }, params[0], .embed_file), .error_name => return simpleUnOp(gz, scope, ri, node, .{ .rl = .{ .ty = .anyerror_type } }, params[0], .error_name), .set_runtime_safety => return simpleUnOp(gz, scope, ri, node, bool_ri, params[0], .set_runtime_safety), @@ -8550,8 +8550,8 @@ fn builtinCall( .shl_exact => return shiftOp(gz, scope, ri, node, params[0], params[1], .shl_exact), .shr_exact => return shiftOp(gz, scope, ri, node, params[0], params[1], .shr_exact), - .bit_offset_of => return offsetOf(gz, scope, ri, node, params[0], params[1], .bit_offset_of), - .offset_of => return offsetOf(gz, scope, ri, node, params[0], params[1], .offset_of), + .bit_offset_of => return offsetOf(gz, scope, ri, node, params[0], params[1], .bit_offset_of), + .offset_of => return offsetOf(gz, scope, ri, node, params[0], params[1], .offset_of), .c_undef => return simpleCBuiltin(gz, scope, ri, node, params[0], .c_undef), .c_include => return simpleCBuiltin(gz, scope, ri, node, params[0], .c_include), diff --git a/src/Sema.zig b/src/Sema.zig index 08d5f02a17..0fcc914596 100644 --- a/src/Sema.zig +++ b/src/Sema.zig @@ -1020,8 +1020,8 @@ fn analyzeBodyInner( .elem_type_index => try sema.zirElemTypeIndex(block, inst), .elem_type => try sema.zirElemType(block, inst), .enum_literal => try sema.zirEnumLiteral(block, inst), - .int_from_enum => try sema.zirIntFromEnum(block, inst), - .enum_from_int => try sema.zirEnumFromInt(block, inst), + .int_from_enum => try sema.zirIntFromEnum(block, inst), + .enum_from_int => try sema.zirEnumFromInt(block, inst), .err_union_code => try sema.zirErrUnionCode(block, inst), .err_union_code_ptr => try sema.zirErrUnionCodePtr(block, inst), .err_union_payload_unsafe => try sema.zirErrUnionPayload(block, inst), @@ -1087,18 +1087,18 @@ fn analyzeBodyInner( .union_init => try sema.zirUnionInit(block, inst), .field_type => try sema.zirFieldType(block, inst), .field_type_ref => try sema.zirFieldTypeRef(block, inst), - .int_from_ptr => try sema.zirIntFromPtr(block, inst), + .int_from_ptr => try sema.zirIntFromPtr(block, inst), .align_of => try sema.zirAlignOf(block, inst), - .int_from_bool => try sema.zirIntFromBool(block, inst), + .int_from_bool => try sema.zirIntFromBool(block, inst), .embed_file => try sema.zirEmbedFile(block, inst), .error_name => try sema.zirErrorName(block, inst), .tag_name => try sema.zirTagName(block, inst), .type_name => try sema.zirTypeName(block, inst), .frame_type => try sema.zirFrameType(block, inst), .frame_size => try sema.zirFrameSize(block, inst), - .int_from_float => try sema.zirIntFromFloat(block, inst), - .float_from_int => try sema.zirFloatFromInt(block, inst), - .ptr_from_int => try sema.zirPtrFromInt(block, inst), + .int_from_float => try sema.zirIntFromFloat(block, inst), + .float_from_int => try sema.zirFloatFromInt(block, inst), + .ptr_from_int => try sema.zirPtrFromInt(block, inst), .float_cast => try sema.zirFloatCast(block, inst), .int_cast => try sema.zirIntCast(block, inst), .ptr_cast => try sema.zirPtrCast(block, inst), @@ -1193,53 +1193,53 @@ fn analyzeBodyInner( const extended = datas[inst].extended; break :ext switch (extended.opcode) { // zig fmt: off - .variable => try sema.zirVarExtended( block, extended), - .struct_decl => try sema.zirStructDecl( block, extended, inst), - .enum_decl => try sema.zirEnumDecl( block, extended, inst), - .union_decl => try sema.zirUnionDecl( block, extended, inst), - .opaque_decl => try sema.zirOpaqueDecl( block, extended, inst), - .this => try sema.zirThis( block, extended), - .ret_addr => try sema.zirRetAddr( block, extended), - .builtin_src => try sema.zirBuiltinSrc( block, extended), - .error_return_trace => try sema.zirErrorReturnTrace( block), - .frame => try sema.zirFrame( block, extended), - .frame_address => try sema.zirFrameAddress( block, extended), - .alloc => try sema.zirAllocExtended( block, extended), - .builtin_extern => try sema.zirBuiltinExtern( block, extended), - .@"asm" => try sema.zirAsm( block, extended, false), - .asm_expr => try sema.zirAsm( block, extended, true), - .typeof_peer => try sema.zirTypeofPeer( block, extended), - .compile_log => try sema.zirCompileLog( extended), - .min_multi => try sema.zirMinMaxMulti( block, extended, .min), - .max_multi => try sema.zirMinMaxMulti( block, extended, .max), - .add_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode), - .sub_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode), - .mul_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode), - .shl_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode), - .c_undef => try sema.zirCUndef( block, extended), - .c_include => try sema.zirCInclude( block, extended), - .c_define => try sema.zirCDefine( block, extended), - .wasm_memory_size => try sema.zirWasmMemorySize( block, extended), - .wasm_memory_grow => try sema.zirWasmMemoryGrow( block, extended), - .prefetch => try sema.zirPrefetch( block, extended), - .err_set_cast => try sema.zirErrSetCast( block, extended), - .await_nosuspend => try sema.zirAwaitNosuspend( block, extended), - .select => try sema.zirSelect( block, extended), - .int_from_error => try sema.zirIntFromError( block, extended), - .error_from_int => try sema.zirErrorFromInt( block, extended), - .reify => try sema.zirReify( block, extended, inst), - .builtin_async_call => try sema.zirBuiltinAsyncCall( block, extended), - .cmpxchg => try sema.zirCmpxchg( block, extended), - .c_va_arg => try sema.zirCVaArg( block, extended), - .c_va_copy => try sema.zirCVaCopy( block, extended), - .c_va_end => try sema.zirCVaEnd( block, extended), - .c_va_start => try sema.zirCVaStart( block, extended), - .ptr_cast_full => try sema.zirPtrCastFull( block, extended), - .ptr_cast_no_dest => try sema.zirPtrCastNoDest( block, extended), - .work_item_id => try sema.zirWorkItem( block, extended, extended.opcode), - .work_group_size => try sema.zirWorkItem( block, extended, extended.opcode), - .work_group_id => try sema.zirWorkItem( block, extended, extended.opcode), - .in_comptime => try sema.zirInComptime( block), + .variable => try sema.zirVarExtended( block, extended), + .struct_decl => try sema.zirStructDecl( block, extended, inst), + .enum_decl => try sema.zirEnumDecl( block, extended, inst), + .union_decl => try sema.zirUnionDecl( block, extended, inst), + .opaque_decl => try sema.zirOpaqueDecl( block, extended, inst), + .this => try sema.zirThis( block, extended), + .ret_addr => try sema.zirRetAddr( block, extended), + .builtin_src => try sema.zirBuiltinSrc( block, extended), + .error_return_trace => try sema.zirErrorReturnTrace( block), + .frame => try sema.zirFrame( block, extended), + .frame_address => try sema.zirFrameAddress( block, extended), + .alloc => try sema.zirAllocExtended( block, extended), + .builtin_extern => try sema.zirBuiltinExtern( block, extended), + .@"asm" => try sema.zirAsm( block, extended, false), + .asm_expr => try sema.zirAsm( block, extended, true), + .typeof_peer => try sema.zirTypeofPeer( block, extended), + .compile_log => try sema.zirCompileLog( extended), + .min_multi => try sema.zirMinMaxMulti( block, extended, .min), + .max_multi => try sema.zirMinMaxMulti( block, extended, .max), + .add_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode), + .sub_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode), + .mul_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode), + .shl_with_overflow => try sema.zirOverflowArithmetic(block, extended, extended.opcode), + .c_undef => try sema.zirCUndef( block, extended), + .c_include => try sema.zirCInclude( block, extended), + .c_define => try sema.zirCDefine( block, extended), + .wasm_memory_size => try sema.zirWasmMemorySize( block, extended), + .wasm_memory_grow => try sema.zirWasmMemoryGrow( block, extended), + .prefetch => try sema.zirPrefetch( block, extended), + .err_set_cast => try sema.zirErrSetCast( block, extended), + .await_nosuspend => try sema.zirAwaitNosuspend( block, extended), + .select => try sema.zirSelect( block, extended), + .int_from_error => try sema.zirIntFromError( block, extended), + .error_from_int => try sema.zirErrorFromInt( block, extended), + .reify => try sema.zirReify( block, extended, inst), + .builtin_async_call => try sema.zirBuiltinAsyncCall( block, extended), + .cmpxchg => try sema.zirCmpxchg( block, extended), + .c_va_arg => try sema.zirCVaArg( block, extended), + .c_va_copy => try sema.zirCVaCopy( block, extended), + .c_va_end => try sema.zirCVaEnd( block, extended), + .c_va_start => try sema.zirCVaStart( block, extended), + .ptr_cast_full => try sema.zirPtrCastFull( block, extended), + .ptr_cast_no_dest => try sema.zirPtrCastNoDest( block, extended), + .work_item_id => try sema.zirWorkItem( block, extended, extended.opcode), + .work_group_size => try sema.zirWorkItem( block, extended, extended.opcode), + .work_group_id => try sema.zirWorkItem( block, extended, extended.opcode), + .in_comptime => try sema.zirInComptime( block), // zig fmt: on .fence => { @@ -12633,6 +12633,10 @@ fn zirEmbedFile(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileError!A const operand_src: LazySrcLoc = .{ .node_offset_builtin_call_arg0 = inst_data.src_node }; const name = try sema.resolveConstString(block, operand_src, inst_data.operand, "file path name must be comptime-known"); + if (name.len == 0) { + return sema.fail(block, operand_src, "file path name cannot be empty", .{}); + } + const embed_file = mod.embedFile(block.getFileScope(mod), name) catch |err| switch (err) { error.ImportOutsidePkgPath => { return sema.fail(block, operand_src, "embed of file outside package path: '{s}'", .{name}); diff --git a/test/cases/compile_errors/@embedFile_with_empty_path.zig b/test/cases/compile_errors/@embedFile_with_empty_path.zig new file mode 100644 index 0000000000..305e8a74cc --- /dev/null +++ b/test/cases/compile_errors/@embedFile_with_empty_path.zig @@ -0,0 +1,11 @@ +const resource = @embedFile(""); + +export fn entry() usize { + return @sizeOf(@TypeOf(resource)); +} + +// error +// backend=stage2 +// target=native +// +// :1:29: error: file path name cannot be empty