From c19bdc2d370f3a72ef492e2f4e6264e2a0dd91ec Mon Sep 17 00:00:00 2001 From: Shawn Landden Date: Mon, 6 May 2019 11:41:15 -0500 Subject: stage1: add @hasField() built-in This was quite straight-forward Closes: #1439 --- src/ir.cpp | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 70 insertions(+) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 91f931462e..fdd7291de3 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -851,6 +851,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeInfo *) { return IrInstructionIdTypeInfo; } +static constexpr IrInstructionId ir_instruction_id(IrInstructionHasField *) { + return IrInstructionIdHasField; +} + static constexpr IrInstructionId ir_instruction_id(IrInstructionTypeId *) { return IrInstructionIdTypeId; } @@ -1280,6 +1284,20 @@ static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode * return &instruction->base; } +static IrInstruction *ir_build_has_field(IrBuilder *irb, Scope *scope, AstNode *source_node, + IrInstruction *container_type, IrInstruction *field_name_expr) +{ + IrInstructionHasField *instruction = ir_build_instruction(irb, scope, source_node); + instruction->container_type = container_type; + instruction->field_name_buffer = nullptr; + instruction->field_name_expr = field_name_expr; + + ir_ref_instruction(container_type, irb->current_basic_block); + ir_ref_instruction(field_name_expr, irb->current_basic_block); + + return &instruction->base; +} + static IrInstruction *ir_build_struct_field_ptr(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *struct_ptr, TypeStructField *field) { @@ -4598,6 +4616,21 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo return ir_build_load_ptr(irb, scope, node, ptr_instruction); } + case BuiltinFnIdHasField: + { + AstNode *arg0_node = node->data.fn_call_expr.params.at(0); + IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_instruction) + return arg0_value; + + AstNode *arg1_node = node->data.fn_call_expr.params.at(1); + IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_instruction) + return arg1_value; + + IrInstruction *type_info = ir_build_has_field(irb, scope, node, arg0_value, arg1_value); + return ir_lval_wrap(irb, scope, type_info, lval); + } case BuiltinFnIdTypeInfo: { AstNode *arg0_node = node->data.fn_call_expr.params.at(0); @@ -20578,6 +20611,40 @@ static IrInstruction *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstr } } +static IrInstruction *ir_analyze_instruction_has_field(IrAnalyze *ira, IrInstructionHasField *instruction) { + Error err; + IrInstruction *container_type_value = instruction->container_type->child; + ZigType *container_type = ir_resolve_type(ira, container_type_value); + if (type_is_invalid(container_type)) + return ira->codegen->invalid_instruction; + + if ((err = ensure_complete_type(ira->codegen, container_type))) + return ira->codegen->invalid_instruction; + + Buf *field_name = instruction->field_name_buffer; + if (!field_name) { + IrInstruction *field_name_expr = instruction->field_name_expr->child; + field_name = ir_resolve_str(ira, field_name_expr); + if (!field_name) + return ira->codegen->invalid_instruction; + } + + bool result; + if (container_type->id == ZigTypeIdStruct) + result = (bool)find_struct_type_field(container_type, field_name); + else if (container_type->id == ZigTypeIdEnum) + result = (bool)find_enum_type_field(container_type, field_name); + else if (container_type->id == ZigTypeIdUnion) + result = (bool)find_union_type_field(container_type, field_name); + else { + ir_add_error(ira, container_type_value, + buf_sprintf("type '%s' does not support @memberName", buf_ptr(&container_type->name))); + return ira->codegen->invalid_instruction; + } + return ir_build_const_bool(&ira->new_irb, + instruction->base.scope, instruction->base.source_node, result); +} + static IrInstruction *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstructionBreakpoint *instruction) { IrInstruction *result = ir_build_breakpoint(&ira->new_irb, instruction->base.scope, instruction->base.source_node); @@ -23068,6 +23135,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio return ir_analyze_instruction_bit_offset_of(ira, (IrInstructionBitOffsetOf *)instruction); case IrInstructionIdTypeInfo: return ir_analyze_instruction_type_info(ira, (IrInstructionTypeInfo *) instruction); + case IrInstructionIdHasField: + return ir_analyze_instruction_has_field(ira, (IrInstructionHasField *) instruction); case IrInstructionIdTypeId: return ir_analyze_instruction_type_id(ira, (IrInstructionTypeId *)instruction); case IrInstructionIdSetEvalBranchQuota: @@ -23355,6 +23424,7 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdByteOffsetOf: case IrInstructionIdBitOffsetOf: case IrInstructionIdTypeInfo: + case IrInstructionIdHasField: case IrInstructionIdTypeId: case IrInstructionIdAlignCast: case IrInstructionIdOpaqueType: -- cgit v1.2.3 From 9b7ad124810e4a3df964927ace449502daa167f9 Mon Sep 17 00:00:00 2001 From: Robert Scott Date: Thu, 9 May 2019 02:28:14 -0700 Subject: Implement @unionInit --- src/all_types.hpp | 13 ++++++ src/codegen.cpp | 2 + src/ir.cpp | 90 ++++++++++++++++++++++++++++++++++++++---- src/ir_print.cpp | 14 +++++++ test/stage1/behavior/union.zig | 37 ++++++++++++++++- 5 files changed, 148 insertions(+), 8 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/all_types.hpp b/src/all_types.hpp index 3b6ac32ea5..2dd70f64f1 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -1471,6 +1471,7 @@ enum BuiltinFnId { BuiltinFnIdErrorReturnTrace, BuiltinFnIdAtomicRmw, BuiltinFnIdAtomicLoad, + BuiltinFnIdUnionInit, }; struct BuiltinFnEntry { @@ -2297,6 +2298,7 @@ enum IrInstructionId { IrInstructionIdArrayToVector, IrInstructionIdAssertZero, IrInstructionIdAssertNonNull, + IrInstructionIdUnionInit2, }; struct IrInstruction { @@ -3503,6 +3505,17 @@ struct IrInstructionAssertNonNull { IrInstruction *target; }; +// TODO, need a better name. Using 2 because there is currently a IrInstructionUnionInit +// It seems like the first one should only be used during the analyze phase, but still +// don't understand it all. +struct IrInstructionUnionInit2 { + IrInstruction base; + + IrInstruction *union_type_value; + IrInstruction *field_name_expr; + IrInstruction *value; +}; + static const size_t slice_ptr_index = 0; static const size_t slice_len_index = 1; diff --git a/src/codegen.cpp b/src/codegen.cpp index 3a34894bb3..39a8c194ac 100644 --- a/src/codegen.cpp +++ b/src/codegen.cpp @@ -5616,6 +5616,7 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable, case IrInstructionIdLoadPtr: case IrInstructionIdBitCast: case IrInstructionIdGlobalAsm: + case IrInstructionIdUnionInit2: zig_unreachable(); case IrInstructionIdDeclVarGen: @@ -7409,6 +7410,7 @@ static void define_builtin_fns(CodeGen *g) { create_builtin_fn(g, BuiltinFnIdToBytes, "sliceToBytes", 1); create_builtin_fn(g, BuiltinFnIdFromBytes, "bytesToSlice", 2); create_builtin_fn(g, BuiltinFnIdThis, "This", 0); + create_builtin_fn(g, BuiltinFnIdUnionInit, "unionInit", 3); } static const char *bool_to_str(bool b) { diff --git a/src/ir.cpp b/src/ir.cpp index 2d81f0c219..643f6845c6 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -188,7 +188,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c assert(get_src_ptr_type(const_val->type) != nullptr); assert(const_val->special == ConstValSpecialStatic); ConstExprValue *result; - + switch (type_has_one_possible_value(g, const_val->type->data.pointer.child_type)) { case OnePossibleValueInvalid: zig_unreachable(); @@ -200,7 +200,7 @@ static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *c case OnePossibleValueNo: break; } - + switch (const_val->data.x_ptr.special) { case ConstPtrSpecialInvalid: zig_unreachable(); @@ -1011,6 +1011,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertNonNull *) return IrInstructionIdAssertNonNull; } +static constexpr IrInstructionId ir_instruction_id(IrInstructionUnionInit2 *) { + return IrInstructionIdUnionInit2; +} + template static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) { T *special_instruction = allocate(1); @@ -1312,6 +1316,7 @@ static IrInstruction *ir_build_union_field_ptr(IrBuilder *irb, Scope *scope, Ast return &instruction->base; } + static IrInstruction *ir_build_call(IrBuilder *irb, Scope *scope, AstNode *source_node, ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args, bool is_comptime, FnInline fn_inline, bool is_async, IrInstruction *async_allocator, @@ -3025,6 +3030,21 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, return &instruction->base; } +static IrInstruction *ir_build_union_init_2(IrBuilder *irb, Scope *scope, AstNode *source_node, + IrInstruction *union_type_value, IrInstruction *field_name_expr, IrInstruction *value) { + IrInstructionUnionInit2 *instruction = ir_build_instruction(irb, scope, source_node); + instruction->union_type_value = union_type_value; + instruction->field_name_expr = field_name_expr; + instruction->value = value; + + ir_ref_instruction(union_type_value, irb->current_basic_block); + ir_ref_instruction(field_name_expr, irb->current_basic_block); + ir_ref_instruction(value, irb->current_basic_block); + + return &instruction->base; +} + + static IrInstruction *ir_build_vector_to_array(IrAnalyze *ira, IrInstruction *source_instruction, IrInstruction *vector, ZigType *result_type) { @@ -3868,7 +3888,7 @@ static void populate_invalid_variable_in_scope(CodeGen *g, Scope *scope, AstNode TldVar *tld_var = allocate(1); init_tld(&tld_var->base, TldIdVar, var_name, VisibModPub, node, &scope_decls->base); tld_var->base.resolution = TldResolutionInvalid; - tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, + tld_var->var = add_variable(g, node, &scope_decls->base, var_name, false, &g->invalid_instruction->value, &tld_var->base, g->builtin_types.entry_invalid); scope_decls->decl_table.put(var_name, &tld_var->base); } @@ -5098,6 +5118,29 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo } return ir_lval_wrap(irb, scope, result, lval); } + case BuiltinFnIdUnionInit: + { + + AstNode *arg0_node = node->data.fn_call_expr.params.at(0); + IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); + if (arg0_value == irb->codegen->invalid_instruction) + return arg0_value; + + AstNode *arg1_node = node->data.fn_call_expr.params.at(1); + IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); + if (arg1_value == irb->codegen->invalid_instruction) + return arg1_value; + + AstNode *arg2_node = node->data.fn_call_expr.params.at(2); + IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); + if (arg2_value == irb->codegen->invalid_instruction) + return arg2_value; + + IrInstruction *result = ir_build_union_init_2(irb, scope, node, arg0_value, arg1_value, arg2_value); + + // TODO: Not sure if we need ir_lval_wrap or not. + return result; + } } zig_unreachable(); } @@ -6328,7 +6371,7 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit prong_values, prong_values_len); var_value = var_is_ptr ? var_ptr_value : ir_build_load_ptr(irb, scope, var_symbol_node, var_ptr_value); } else { - var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, + var_value = var_is_ptr ? target_value_ptr : ir_build_load_ptr(irb, scope, var_symbol_node, target_value_ptr); } IrInstruction *var_type = nullptr; // infer the type @@ -12372,7 +12415,7 @@ static IrInstruction *ir_analyze_bin_op_cmp(IrAnalyze *ira, IrInstructionBinOp * } else { return is_non_null; } - } else if (is_equality_cmp && + } else if (is_equality_cmp && ((op1->value.type->id == ZigTypeIdNull && op2->value.type->id == ZigTypeIdPointer && op2->value.type->data.pointer.ptr_len == PtrLenC) || (op2->value.type->id == ZigTypeIdNull && op1->value.type->id == ZigTypeIdPointer && @@ -19383,7 +19426,7 @@ static IrInstruction *ir_analyze_instruction_c_import(IrAnalyze *ira, IrInstruct ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to make dir: %s", err_str(err))); return ira->codegen->invalid_instruction; } - + if ((err = os_write_file(&tmp_c_file_path, &cimport_scope->buf))) { ir_add_error_node(ira, node, buf_sprintf("C import failed: unable to write .h file: %s", err_str(err))); return ira->codegen->invalid_instruction; @@ -20333,7 +20376,7 @@ static IrInstruction *ir_analyze_instruction_memcpy(IrAnalyze *ira, IrInstructio return ira->codegen->invalid_instruction; // TODO test this at comptime with u8 and non-u8 types - // TODO test with dest ptr being a global runtime variable + // TODO test with dest ptr being a global runtime variable if (casted_dest_ptr->value.special == ConstValSpecialStatic && casted_src_ptr->value.special == ConstValSpecialStatic && casted_count->value.special == ConstValSpecialStatic && @@ -23151,6 +23194,35 @@ static IrInstruction *ir_analyze_instruction_check_runtime_scope(IrAnalyze *ira, return ir_const_void(ira, &instruction->base); } +static IrInstruction *ir_analyze_instruction_union_init_2(IrAnalyze *ira, IrInstructionUnionInit2 *union_init_instruction) +{ + Error err; + IrInstruction *union_type_value = union_init_instruction->union_type_value->child; + ZigType *union_type = ir_resolve_type(ira, union_type_value); + if (type_is_invalid(union_type)) { + return ira->codegen->invalid_instruction; + } + + if (union_type->id != ZigTypeIdUnion) + return ira->codegen->invalid_instruction; + + if ((err = ensure_complete_type(ira->codegen, union_type))) + return ira->codegen->invalid_instruction; + + IrInstruction *field_name_expr = union_init_instruction->field_name_expr->child; + Buf *field_name = ir_resolve_str(ira, field_name_expr); + if (!field_name) + return ira->codegen->invalid_instruction; + + IrInstructionContainerInitFieldsField *fields = allocate(1); + + fields[0].name = field_name; + fields[0].value = union_init_instruction->value; + fields[0].source_node = union_init_instruction->base.source_node; + + return ir_analyze_container_init_fields_union(ira, &union_init_instruction->base, union_type, 1, fields); +} + static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) { switch (instruction->id) { case IrInstructionIdInvalid: @@ -23445,6 +23517,8 @@ static IrInstruction *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructio return ir_analyze_instruction_enum_to_int(ira, (IrInstructionEnumToInt *)instruction); case IrInstructionIdCheckRuntimeScope: return ir_analyze_instruction_check_runtime_scope(ira, (IrInstructionCheckRuntimeScope *)instruction); + case IrInstructionIdUnionInit2: + return ir_analyze_instruction_union_init_2(ira, (IrInstructionUnionInit2 *)instruction); } zig_unreachable(); } @@ -23681,6 +23755,8 @@ bool ir_has_side_effects(IrInstruction *instruction) { case IrInstructionIdEnumToInt: case IrInstructionIdVectorToArray: case IrInstructionIdArrayToVector: + case IrInstructionIdUnionInit2: + return false; case IrInstructionIdAsm: diff --git a/src/ir_print.cpp b/src/ir_print.cpp index d38b552749..6d98580d02 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -1453,6 +1453,17 @@ static void ir_print_decl_var_gen(IrPrint *irp, IrInstructionDeclVarGen *decl_va } } + +static void ir_print_uniont_init_2(IrPrint *irp, IrInstructionUnionInit2 *instruction) { + fprintf(irp->f, "@unionInit("); + ir_print_other_instruction(irp, instruction->union_type_value); + fprintf(irp->f, ", "); + ir_print_other_instruction(irp, instruction->field_name_expr); + fprintf(irp->f, ", "); + ir_print_other_instruction(irp, instruction->value); + fprintf(irp->f, ")"); +} + static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { ir_print_prefix(irp, instruction); switch (instruction->id) { @@ -1920,6 +1931,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) { case IrInstructionIdResizeSlice: ir_print_resize_slice(irp, (IrInstructionResizeSlice *)instruction); break; + case IrInstructionIdUnionInit2: + ir_print_uniont_init_2(irp, (IrInstructionUnionInit2 *)instruction); + break; } fprintf(irp->f, "\n"); } diff --git a/test/stage1/behavior/union.zig b/test/stage1/behavior/union.zig index b8bb9a51b8..be96b659f6 100644 --- a/test/stage1/behavior/union.zig +++ b/test/stage1/behavior/union.zig @@ -374,7 +374,7 @@ const Attribute = union(enum) { fn setAttribute(attr: Attribute) void {} fn Setter(attr: Attribute) type { - return struct{ + return struct { fn set() void { setAttribute(attr); } @@ -402,3 +402,38 @@ test "comptime union field value equality" { expect(a0 != a1); expect(b0 != b1); } + +test "unionInit can modify a union type" { + const UnionInitEnum = union(enum) { + Boolean: bool, + Byte: u8, + }; + + var value: UnionInitEnum = undefined; + + value = @unionInit(UnionInitEnum, "Boolean", true); + expect(value.Boolean == true); + value.Boolean = false; + expect(value.Boolean == false); + + value = @unionInit(UnionInitEnum, "Byte", 2); + expect(value.Byte == 2); + value.Byte = 3; + expect(value.Byte == 3); +} + +test "unionInit can modify a pointer value" { + const UnionInitEnum = union(enum) { + Boolean: bool, + Byte: u8, + }; + + var value: UnionInitEnum = undefined; + var value_ptr = &value; + + value_ptr.* = @unionInit(UnionInitEnum, "Boolean", true); + expect(value.Boolean == true); + + value_ptr.* = @unionInit(UnionInitEnum, "Byte", 2); + expect(value.Byte == 2); +} -- cgit v1.2.3 From 1ccf6a2c9e7b42214be07185467e7ae7029a0aa5 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 27 Jun 2019 12:24:13 -0400 Subject: compile error for using slice as array init expr type when there are more than 0 elements. closes #2764 --- src/ir.cpp | 8 ++++++-- test/compile_errors.zig | 11 ++++++++++- 2 files changed, 16 insertions(+), 3 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 887e0fc8bf..b0e8c2d8ee 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -17280,7 +17280,11 @@ static IrInstruction *ir_analyze_instruction_elem_ptr(IrAnalyze *ira, IrInstruct ZigType *actual_array_type = ir_resolve_type(ira, elem_ptr_instruction->init_array_type->child); if (type_is_invalid(actual_array_type)) return ira->codegen->invalid_instruction; - assert(actual_array_type->id == ZigTypeIdArray); + if (actual_array_type->id != ZigTypeIdArray) { + ir_add_error(ira, elem_ptr_instruction->init_array_type, + buf_sprintf("expected array type or [_], found slice")); + return ira->codegen->invalid_instruction; + } ConstExprValue *array_init_val = create_const_vals(1); array_init_val->special = ConstValSpecialStatic; @@ -19575,7 +19579,7 @@ static IrInstruction *ir_analyze_instruction_container_init_list(IrAnalyze *ira, size_t elem_count = instruction->item_count; if (is_slice(container_type)) { - ir_add_error(ira, &instruction->base, + ir_add_error(ira, instruction->container_type, buf_sprintf("expected array type or [_], found slice")); return ira->codegen->invalid_instruction; } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 9e92681fdb..94cd152eb7 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2,13 +2,22 @@ const tests = @import("tests.zig"); const builtin = @import("builtin"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.add( + "slice passed as array init type with elems", + \\export fn entry() void { + \\ const x = []u8{1, 2}; + \\} + , + "tmp.zig:2:15: error: expected array type or [_], found slice", + ); + cases.add( "slice passed as array init type", \\export fn entry() void { \\ const x = []u8{}; \\} , - "tmp.zig:2:19: error: expected array type or [_], found slice", + "tmp.zig:2:15: error: expected array type or [_], found slice", ); cases.add( -- cgit v1.2.3 From 1b23c461380dea2a2b04eb234652a705f01f05a7 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 27 Jun 2019 16:54:19 -0400 Subject: fix switch with null and T peer types and inferred result location type closes #2762 --- src/ir.cpp | 8 ++++---- test/stage1/behavior/switch.zig | 15 +++++++++++++++ 2 files changed, 19 insertions(+), 4 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index b0e8c2d8ee..74f6d0485d 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -7156,7 +7156,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * ir_set_cursor_at_end_and_append_block(irb, else_block); if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values, - &switch_else_var, lval, &this_peer_result_loc->base)) + &switch_else_var, LValNone, &this_peer_result_loc->base)) { return irb->codegen->invalid_instruction; } @@ -7233,7 +7233,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * ir_set_cursor_at_end_and_append_block(irb, range_block_yes); if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, - &incoming_blocks, &incoming_values, nullptr, lval, &this_peer_result_loc->base)) + &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) { return irb->codegen->invalid_instruction; } @@ -7283,7 +7283,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * ir_set_cursor_at_end_and_append_block(irb, prong_block); if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block, is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count, - &incoming_blocks, &incoming_values, nullptr, lval, &this_peer_result_loc->base)) + &incoming_blocks, &incoming_values, nullptr, LValNone, &this_peer_result_loc->base)) { return irb->codegen->invalid_instruction; } @@ -7334,7 +7334,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode * result_instruction = ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items, peer_parent); } - return ir_expr_wrap(irb, scope, result_instruction, result_loc); + return ir_lval_wrap(irb, scope, result_instruction, lval, result_loc); } static IrInstruction *ir_gen_comptime(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval) { diff --git a/test/stage1/behavior/switch.zig b/test/stage1/behavior/switch.zig index 0f74764d46..12e026d0ba 100644 --- a/test/stage1/behavior/switch.zig +++ b/test/stage1/behavior/switch.zig @@ -376,3 +376,18 @@ test "return result loc and then switch with range implicit casted to error unio S.doTheTest(); comptime S.doTheTest(); } + +test "switch with null and T peer types and inferred result location type" { + const S = struct { + fn doTheTest(c: u8) void { + if (switch (c) { + 0 => true, + else => null, + }) |v| { + @panic("fail"); + } + } + }; + S.doTheTest(1); + comptime S.doTheTest(1); +} -- cgit v1.2.3 From 0a0c11685fd8faf73392d88dbdee7c744cc83386 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 27 Jun 2019 17:22:35 -0400 Subject: fix for with null and T peer types and inferred result location type See #2762 --- src/ir.cpp | 6 +++--- test/stage1/behavior/for.zig | 16 ++++++++++++++++ 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 74f6d0485d..abae52fcb5 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -6521,7 +6521,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo loop_scope->is_comptime = is_comptime; loop_scope->incoming_blocks = &incoming_blocks; loop_scope->incoming_values = &incoming_values; - loop_scope->lval = lval; + loop_scope->lval = LValNone; loop_scope->peer_parent = peer_parent; // Note the body block of the loop is not the place that lval and result_loc are used - @@ -6548,7 +6548,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo } ResultLocPeer *peer_result = create_peer_result(peer_parent); peer_parent->peers.append(peer_result); - else_result = ir_gen_node_extra(irb, else_node, parent_scope, lval, &peer_result->base); + else_result = ir_gen_node_extra(irb, else_node, parent_scope, LValNone, &peer_result->base); if (else_result == irb->codegen->invalid_instruction) return else_result; if (!instr_is_unreachable(else_result)) @@ -6570,7 +6570,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo IrInstruction *phi = ir_build_phi(irb, parent_scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items, peer_parent); - return ir_expr_wrap(irb, parent_scope, phi, result_loc); + return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); } static IrInstruction *ir_gen_bool_literal(IrBuilder *irb, Scope *scope, AstNode *node) { diff --git a/test/stage1/behavior/for.zig b/test/stage1/behavior/for.zig index 63205b9e7d..cfa68bd216 100644 --- a/test/stage1/behavior/for.zig +++ b/test/stage1/behavior/for.zig @@ -126,3 +126,19 @@ test "2 break statements and an else" { S.entry(true, false); comptime S.entry(true, false); } + +test "for with null and T peer types and inferred result location type" { + const S = struct { + fn doTheTest(slice: []const u8) void { + if (for (slice) |item| { + if (item == 10) { + break item; + } + } else null) |v| { + @panic("fail"); + } + } + }; + S.doTheTest([_]u8{ 1, 2 }); + comptime S.doTheTest([_]u8{ 1, 2 }); +} -- cgit v1.2.3 From 2d85ff94653457ea12cd9ab0984ab3b13c9b41e5 Mon Sep 17 00:00:00 2001 From: emekoi Date: Mon, 1 Jul 2019 00:27:55 -0500 Subject: added invalid switch prong error added error for switch prong with different payloads and support for capturing payload on switch prongs with payloads of the same type --- src/ir.cpp | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index abae52fcb5..d4cb5f90de 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -19128,10 +19128,6 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru assert(enum_type != nullptr); assert(enum_type->id == ZigTypeIdEnum); - if (instruction->prongs_len != 1) { - return target_value_ptr; - } - IrInstruction *prong_value = instruction->prongs_ptr[0]->child; if (type_is_invalid(prong_value->value.type)) return ira->codegen->invalid_instruction; @@ -19146,6 +19142,40 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru TypeUnionField *field = find_union_field_by_tag(target_type, &prong_val->data.x_enum_tag); + if (instruction->prongs_len != 1) { + ErrorMsg *invalid_payload = nullptr; + Buf *invalid_payload_list = nullptr; + + for (size_t i = 1; i < instruction->prongs_len; i++) { + IrInstruction *casted_prong_value = ir_implicit_cast(ira, instruction->prongs_ptr[i]->child, enum_type); + if (type_is_invalid(casted_prong_value->value.type)) + return ira->codegen->invalid_instruction; + + ConstExprValue *next_prong = ir_resolve_const(ira, casted_prong_value, UndefBad); + if (!next_prong) + return ira->codegen->invalid_instruction; + + ZigType *payload = find_union_field_by_tag(target_type, &next_prong->data.x_enum_tag)->type_entry; + + if (field->type_entry != payload) { + if (!invalid_payload) { + invalid_payload = ir_add_error(ira, &instruction->base, + buf_sprintf("switch prong contains cases with differing payloads")); + invalid_payload_list = buf_sprintf("types %s", buf_ptr(&field->type_entry->name)); + } + + if (i == instruction->prongs_len - 1) + buf_append_buf(invalid_payload_list, buf_sprintf(" and %s", buf_ptr(&payload->name))); + else + buf_append_buf(invalid_payload_list, buf_sprintf(", %s", buf_ptr(&payload->name))); + } + } + + if (invalid_payload) + add_error_note(ira->codegen, invalid_payload, + ((IrInstruction*)instruction)->source_node, invalid_payload_list); + } + if (instr_is_comptime(target_value_ptr)) { ConstExprValue *target_val_ptr = ir_resolve_const(ira, target_value_ptr, UndefBad); if (!target_value_ptr) -- cgit v1.2.3 From df11512f85e5228ee2393e9dc5fc42294ecba1c9 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 2 Jul 2019 16:52:55 -0400 Subject: fixups --- doc/langref.html.in | 23 +++++++++++--------- src/all_types.hpp | 3 +-- src/ir.cpp | 45 +++++++++++++++++---------------------- src/ir_print.cpp | 2 +- test/compile_errors.zig | 9 ++++++++ test/stage1/behavior/hasfield.zig | 11 ++++++++-- 6 files changed, 52 insertions(+), 41 deletions(-) (limited to 'src/ir.cpp') diff --git a/doc/langref.html.in b/doc/langref.html.in index 78c2723148..fda741930b 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -6801,6 +6801,19 @@ test "@hasDecl" { assert(!@hasDecl(Foo, "nope1234")); } {#code_end#} + {#see_also|@hasField#} + {#header_close#} + + {#header_open|@hasField#} +
{#syntax#}@hasField(comptime T: type, comptime name: []const u8) bool{#endsyntax#}
+

Returns whether the field name of a struct, union, or enum exists.

+

+ The result is a compile time constant. +

+

+ It does not include functions, variables, or constants. +

+ {#see_also|@hasDecl#} {#header_close#} {#header_open|@import#} @@ -6940,16 +6953,6 @@ fn add(a: i32, b: i32) i32 { return a + b; } It does not include functions, variables, or constants.

{#header_close#} - {#header_open|@hasField#} -
{#syntax#}@hasField(comptime T: type, comptime name: []const u8) bool{#endsyntax#}
-

Returns if the field name of a struct, union, or enum exists.

-

- The result is a compile time constant. -

-

- It does not include functions, variables, constants. -

- {#header_close#} {#header_open|@memberType#}
{#syntax#}@memberType(comptime T: type, comptime index: usize) type{#endsyntax#}

Returns the field type of a struct or union.

diff --git a/src/all_types.hpp b/src/all_types.hpp index ada08983a6..a9304fdd0f 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -3339,8 +3339,7 @@ struct IrInstructionHasField { IrInstruction base; IrInstruction *container_type; - Buf *field_name_buffer; - IrInstruction *field_name_expr; + IrInstruction *field_name; }; struct IrInstructionTypeId { diff --git a/src/ir.cpp b/src/ir.cpp index 6f3ea2220b..e6cc5f2342 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -1380,15 +1380,14 @@ static IrInstruction *ir_build_field_ptr(IrBuilder *irb, Scope *scope, AstNode * } static IrInstruction *ir_build_has_field(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *container_type, IrInstruction *field_name_expr) + IrInstruction *container_type, IrInstruction *field_name) { IrInstructionHasField *instruction = ir_build_instruction(irb, scope, source_node); instruction->container_type = container_type; - instruction->field_name_buffer = nullptr; - instruction->field_name_expr = field_name_expr; + instruction->field_name = field_name; ir_ref_instruction(container_type, irb->current_basic_block); - ir_ref_instruction(field_name_expr, irb->current_basic_block); + ir_ref_instruction(field_name, irb->current_basic_block); return &instruction->base; } @@ -5132,7 +5131,7 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo return arg1_value; IrInstruction *type_info = ir_build_has_field(irb, scope, node, arg0_value, arg1_value); - return ir_lval_wrap(irb, scope, type_info, lval); + return ir_lval_wrap(irb, scope, type_info, lval, result_loc); } case BuiltinFnIdTypeInfo: { @@ -22655,36 +22654,30 @@ static IrInstruction *ir_analyze_instruction_member_name(IrAnalyze *ira, IrInstr static IrInstruction *ir_analyze_instruction_has_field(IrAnalyze *ira, IrInstructionHasField *instruction) { Error err; - IrInstruction *container_type_value = instruction->container_type->child; - ZigType *container_type = ir_resolve_type(ira, container_type_value); + ZigType *container_type = ir_resolve_type(ira, instruction->container_type->child); if (type_is_invalid(container_type)) return ira->codegen->invalid_instruction; - if ((err = ensure_complete_type(ira->codegen, container_type))) + if ((err = type_resolve(ira->codegen, container_type, ResolveStatusZeroBitsKnown))) return ira->codegen->invalid_instruction; - Buf *field_name = instruction->field_name_buffer; - if (!field_name) { - IrInstruction *field_name_expr = instruction->field_name_expr->child; - field_name = ir_resolve_str(ira, field_name_expr); - if (!field_name) - return ira->codegen->invalid_instruction; - } + Buf *field_name = ir_resolve_str(ira, instruction->field_name->child); + if (field_name == nullptr) + return ira->codegen->invalid_instruction; bool result; - if (container_type->id == ZigTypeIdStruct) - result = (bool)find_struct_type_field(container_type, field_name); - else if (container_type->id == ZigTypeIdEnum) - result = (bool)find_enum_type_field(container_type, field_name); - else if (container_type->id == ZigTypeIdUnion) - result = (bool)find_union_type_field(container_type, field_name); - else { - ir_add_error(ira, container_type_value, - buf_sprintf("type '%s' does not support @memberName", buf_ptr(&container_type->name))); + if (container_type->id == ZigTypeIdStruct) { + result = find_struct_type_field(container_type, field_name) != nullptr; + } else if (container_type->id == ZigTypeIdEnum) { + result = find_enum_type_field(container_type, field_name) != nullptr; + } else if (container_type->id == ZigTypeIdUnion) { + result = find_union_type_field(container_type, field_name) != nullptr; + } else { + ir_add_error(ira, instruction->container_type, + buf_sprintf("type '%s' does not support @hasField", buf_ptr(&container_type->name))); return ira->codegen->invalid_instruction; } - return ir_build_const_bool(&ira->new_irb, - instruction->base.scope, instruction->base.source_node, result); + return ir_const_bool(ira, &instruction->base, result); } static IrInstruction *ir_analyze_instruction_breakpoint(IrAnalyze *ira, IrInstructionBreakpoint *instruction) { diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 3b6ee3273e..31b7e608b7 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -1274,7 +1274,7 @@ static void ir_print_has_field(IrPrint *irp, IrInstructionHasField *instruction) fprintf(irp->f, "@hasField("); ir_print_other_instruction(irp, instruction->container_type); fprintf(irp->f, ","); - ir_print_other_instruction(irp, instruction->field_name_expr); + ir_print_other_instruction(irp, instruction->field_name); fprintf(irp->f, ")"); } diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 94cd152eb7..e0ac76bbf0 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2,6 +2,15 @@ const tests = @import("tests.zig"); const builtin = @import("builtin"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.add( + "wrong type to @hasField", + \\export fn entry() bool { + \\ return @hasField(i32, "hi"); + \\} + , + "tmp.zig:2:22: error: type 'i32' does not support @hasField", + ); + cases.add( "slice passed as array init type with elems", \\export fn entry() void { diff --git a/test/stage1/behavior/hasfield.zig b/test/stage1/behavior/hasfield.zig index 0e18cb19b5..c179fedd56 100644 --- a/test/stage1/behavior/hasfield.zig +++ b/test/stage1/behavior/hasfield.zig @@ -5,26 +5,33 @@ test "@hasField" { const struc = struct { a: i32, b: []u8, + + pub const nope = 1; }; expect(@hasField(struc, "a") == true); expect(@hasField(struc, "b") == true); expect(@hasField(struc, "non-existant") == false); + expect(@hasField(struc, "nope") == false); const unin = union { a: u64, b: []u16, + + pub const nope = 1; }; expect(@hasField(unin, "a") == true); expect(@hasField(unin, "b") == true); expect(@hasField(unin, "non-existant") == false); + expect(@hasField(unin, "nope") == false); const enm = enum { a, b, + + pub const nope = 1; }; expect(@hasField(enm, "a") == true); expect(@hasField(enm, "b") == true); expect(@hasField(enm, "non-existant") == false); - - expect(@hasField(builtin, "os") == true); + expect(@hasField(enm, "nope") == false); } -- cgit v1.2.3 From 9daf0140e5a78802fd294bce8a9019f59bd89b61 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Tue, 2 Jul 2019 21:14:42 -0400 Subject: add missing compile error for comptime continue inside runtime catch See #2604 --- src/ir.cpp | 7 ++++--- test/compile_errors.zig | 16 ++++++++++++++++ 2 files changed, 20 insertions(+), 3 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index e6cc5f2342..b9afe405b9 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -7624,26 +7624,27 @@ static IrInstruction *ir_gen_catch(IrBuilder *irb, Scope *parent_scope, AstNode is_comptime); ir_set_cursor_at_end_and_append_block(irb, err_block); + Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, parent_scope, is_comptime); Scope *err_scope; if (var_node) { assert(var_node->type == NodeTypeSymbol); Buf *var_name = var_node->data.symbol_expr.symbol; bool is_const = true; bool is_shadowable = false; - ZigVar *var = ir_create_var(irb, node, parent_scope, var_name, + ZigVar *var = ir_create_var(irb, node, subexpr_scope, var_name, is_const, is_const, is_shadowable, is_comptime); err_scope = var->child_scope; IrInstruction *err_ptr = ir_build_unwrap_err_code(irb, err_scope, node, err_union_ptr); ir_build_var_decl_src(irb, err_scope, var_node, var, nullptr, err_ptr); } else { - err_scope = parent_scope; + err_scope = subexpr_scope; } IrInstruction *err_result = ir_gen_node_extra(irb, op2_node, err_scope, LValNone, &peer_parent->peers.at(0)->base); if (err_result == irb->codegen->invalid_instruction) return irb->codegen->invalid_instruction; IrBasicBlock *after_err_block = irb->current_basic_block; if (!instr_is_unreachable(err_result)) - ir_mark_gen(ir_build_br(irb, err_scope, node, end_block, is_comptime)); + ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); ir_set_cursor_at_end_and_append_block(irb, ok_block); IrInstruction *unwrapped_ptr = ir_build_unwrap_err_payload(irb, parent_scope, node, err_union_ptr, false, false); diff --git a/test/compile_errors.zig b/test/compile_errors.zig index e0ac76bbf0..c411ba46f6 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -1148,6 +1148,22 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:4:5: error: no-inline call of inline function", ); + cases.add( + "comptime continue inside runtime catch", + \\export fn entry(c: bool) void { + \\ const ints = [_]u8{ 1, 2 }; + \\ inline for (ints) |_| { + \\ bad() catch |_| continue; + \\ } + \\} + \\fn bad() !void { + \\ return error.Bad; + \\} + , + "tmp.zig:4:25: error: comptime control flow inside runtime block", + "tmp.zig:4:15: note: runtime block created here", + ); + cases.add( "comptime continue inside runtime switch", \\export fn entry() void { -- cgit v1.2.3 From 4bae87764fc455f4df8b9d96be856921b0dd97db Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 3 Jul 2019 13:40:40 -0400 Subject: update `@unionInit` to integrate with result location semantics --- doc/langref.html.in | 17 ++++++ src/all_types.hpp | 3 +- src/ir.cpp | 167 ++++++++++++++++++++++++++++++---------------------- src/ir_print.cpp | 4 +- 4 files changed, 118 insertions(+), 73 deletions(-) (limited to 'src/ir.cpp') diff --git a/doc/langref.html.in b/doc/langref.html.in index fda741930b..ef914375f4 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -5065,6 +5065,12 @@ test "@intToPtr for pointer to zero bit type" { {#header_close#} {#header_close#} + {#header_open|Result Location Semantics#} +

+ TODO add documentation for this +

+ {#header_close#} + {#header_open|comptime#}

Zig places importance on the concept of whether an expression is known at compile-time. @@ -7809,6 +7815,17 @@ pub const TypeInfo = union(TypeId) { {#header_close#} + {#header_open|@unionInit#} +

{#syntax#}@unionInit(comptime Union: type, comptime active_field_name: []const u8, init_expr) Union{#endsyntax#}
+

+ This is the same thing as {#link|union#} initialization syntax, except that the field name is a + {#link|comptime#}-known value rather than an identifier token. +

+

+ {#syntax#}@unionInit{#endsyntax#} forwards its {#link|result location|Result Location Semantics#} to {#syntax#}init_expr{#endsyntax#}. +

+ {#header_close#} + {#header_open|@Vector#}
{#syntax#}@Vector(comptime len: u32, comptime ElemType: type) type{#endsyntax#}

diff --git a/src/all_types.hpp b/src/all_types.hpp index 0d187a1c4e..c1e54baf8d 100644 --- a/src/all_types.hpp +++ b/src/all_types.hpp @@ -3610,7 +3610,8 @@ struct IrInstructionUnionInitNamedField { IrInstruction *union_type; IrInstruction *field_name; - IrInstruction *value; + IrInstruction *field_result_loc; + IrInstruction *result_loc; }; struct IrInstructionHasDecl { diff --git a/src/ir.cpp b/src/ir.cpp index 594f61982a..6b19ce2909 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -198,6 +198,9 @@ static IrInstruction *ir_analyze_unwrap_err_code(IrAnalyze *ira, IrInstruction * IrInstruction *base_ptr, bool initializing); static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *ptr, IrInstruction *uncasted_value); +static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, + IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node, + LVal lval, ResultLoc *parent_result_loc); static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) { assert(get_src_ptr_type(const_val->type) != nullptr); @@ -1069,7 +1072,6 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionAssertNonNull *) return IrInstructionIdAssertNonNull; } -<<<<<<< HEAD static constexpr IrInstructionId ir_instruction_id(IrInstructionHasDecl *) { return IrInstructionIdHasDecl; } @@ -1357,12 +1359,13 @@ static IrInstruction *ir_build_elem_ptr(IrBuilder *irb, Scope *scope, AstNode *s } static IrInstruction *ir_build_field_ptr_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *container_ptr, IrInstruction *field_name_expr) + IrInstruction *container_ptr, IrInstruction *field_name_expr, bool initializing) { IrInstructionFieldPtr *instruction = ir_build_instruction(irb, scope, source_node); instruction->container_ptr = container_ptr; instruction->field_name_buffer = nullptr; instruction->field_name_expr = field_name_expr; + instruction->initializing = initializing; ir_ref_instruction(container_ptr, irb->current_basic_block); ir_ref_instruction(field_name_expr, irb->current_basic_block); @@ -3329,16 +3332,19 @@ static IrInstruction *ir_build_check_runtime_scope(IrBuilder *irb, Scope *scope, return &instruction->base; } -static IrInstruction *ir_build_union_init_2(IrBuilder *irb, Scope *scope, AstNode *source_node, - IrInstruction *union_type_value, IrInstruction *field_name_expr, IrInstruction *value) { - IrInstructionUnionInit2 *instruction = ir_build_instruction(irb, scope, source_node); - instruction->union_type_value = union_type_value; - instruction->field_name_expr = field_name_expr; - instruction->value = value; +static IrInstruction *ir_build_union_init_named_field(IrBuilder *irb, Scope *scope, AstNode *source_node, + IrInstruction *union_type, IrInstruction *field_name, IrInstruction *field_result_loc, IrInstruction *result_loc) +{ + IrInstructionUnionInitNamedField *instruction = ir_build_instruction(irb, scope, source_node); + instruction->union_type = union_type; + instruction->field_name = field_name; + instruction->field_result_loc = field_result_loc; + instruction->result_loc = result_loc; - ir_ref_instruction(union_type_value, irb->current_basic_block); - ir_ref_instruction(field_name_expr, irb->current_basic_block); - ir_ref_instruction(value, irb->current_basic_block); + ir_ref_instruction(union_type, irb->current_basic_block); + ir_ref_instruction(field_name, irb->current_basic_block); + ir_ref_instruction(field_result_loc, irb->current_basic_block); + if (result_loc != nullptr) ir_ref_instruction(result_loc, irb->current_basic_block); return &instruction->base; } @@ -5130,7 +5136,8 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo if (arg1_value == irb->codegen->invalid_instruction) return arg1_value; - IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, arg0_value, arg1_value); + IrInstruction *ptr_instruction = ir_build_field_ptr_instruction(irb, scope, node, + arg0_value, arg1_value, false); if (lval == LValPtr) return ptr_instruction; @@ -5673,26 +5680,20 @@ static IrInstruction *ir_gen_builtin_fn_call(IrBuilder *irb, Scope *scope, AstNo } case BuiltinFnIdUnionInit: { + AstNode *union_type_node = node->data.fn_call_expr.params.at(0); + IrInstruction *union_type_inst = ir_gen_node(irb, union_type_node, scope); + if (union_type_inst == irb->codegen->invalid_instruction) + return union_type_inst; - AstNode *arg0_node = node->data.fn_call_expr.params.at(0); - IrInstruction *arg0_value = ir_gen_node(irb, arg0_node, scope); - if (arg0_value == irb->codegen->invalid_instruction) - return arg0_value; - - AstNode *arg1_node = node->data.fn_call_expr.params.at(1); - IrInstruction *arg1_value = ir_gen_node(irb, arg1_node, scope); - if (arg1_value == irb->codegen->invalid_instruction) - return arg1_value; - - AstNode *arg2_node = node->data.fn_call_expr.params.at(2); - IrInstruction *arg2_value = ir_gen_node(irb, arg2_node, scope); - if (arg2_value == irb->codegen->invalid_instruction) - return arg2_value; + AstNode *name_node = node->data.fn_call_expr.params.at(1); + IrInstruction *name_inst = ir_gen_node(irb, name_node, scope); + if (name_inst == irb->codegen->invalid_instruction) + return name_inst; - IrInstruction *result = ir_build_union_init_2(irb, scope, node, arg0_value, arg1_value, arg2_value); + AstNode *init_node = node->data.fn_call_expr.params.at(2); - // TODO: Not sure if we need ir_lval_wrap or not. - return result; + return ir_gen_union_init_expr(irb, scope, node, union_type_inst, name_inst, init_node, + lval, result_loc); } } zig_unreachable(); @@ -5972,6 +5973,31 @@ static IrInstruction *ir_gen_prefix_op_expr(IrBuilder *irb, Scope *scope, AstNod zig_unreachable(); } +static IrInstruction *ir_gen_union_init_expr(IrBuilder *irb, Scope *scope, AstNode *source_node, + IrInstruction *union_type, IrInstruction *field_name, AstNode *expr_node, + LVal lval, ResultLoc *parent_result_loc) +{ + IrInstruction *container_ptr = ir_build_resolve_result(irb, scope, source_node, parent_result_loc, union_type); + IrInstruction *field_ptr = ir_build_field_ptr_instruction(irb, scope, source_node, container_ptr, + field_name, true); + + ResultLocInstruction *result_loc_inst = allocate(1); + result_loc_inst->base.id = ResultLocIdInstruction; + result_loc_inst->base.source_instruction = field_ptr; + ir_ref_instruction(field_ptr, irb->current_basic_block); + ir_build_reset_result(irb, scope, expr_node, &result_loc_inst->base); + + IrInstruction *expr_value = ir_gen_node_extra(irb, expr_node, scope, LValNone, + &result_loc_inst->base); + if (expr_value == irb->codegen->invalid_instruction) + return expr_value; + + IrInstruction *init_union = ir_build_union_init_named_field(irb, scope, source_node, union_type, + field_name, field_ptr, container_ptr); + + return ir_lval_wrap(irb, scope, init_union, lval, parent_result_loc); +} + static IrInstruction *ir_gen_container_init_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *parent_result_loc) { @@ -19451,32 +19477,21 @@ static IrInstruction *ir_analyze_instruction_ref(IrAnalyze *ira, IrInstructionRe return ir_get_ref(ira, &ref_instruction->base, value, ref_instruction->is_const, ref_instruction->is_volatile); } -static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrInstruction *instruction, - ZigType *container_type, size_t instr_field_count, IrInstructionContainerInitFieldsField *fields, - IrInstruction *result_loc) +static IrInstruction *ir_analyze_union_init(IrAnalyze *ira, IrInstruction *source_instruction, + AstNode *field_source_node, ZigType *union_type, Buf *field_name, IrInstruction *field_result_loc, + IrInstruction *result_loc) { Error err; - assert(container_type->id == ZigTypeIdUnion); - - if ((err = type_resolve(ira->codegen, container_type, ResolveStatusSizeKnown))) - return ira->codegen->invalid_instruction; - - if (instr_field_count != 1) { - ir_add_error(ira, instruction, - buf_sprintf("union initialization expects exactly one field")); - return ira->codegen->invalid_instruction; - } + assert(union_type->id == ZigTypeIdUnion); - IrInstructionContainerInitFieldsField *field = &fields[0]; - IrInstruction *field_result_loc = field->result_loc->child; - if (type_is_invalid(field_result_loc->value.type)) + if ((err = type_resolve(ira->codegen, union_type, ResolveStatusSizeKnown))) return ira->codegen->invalid_instruction; - TypeUnionField *type_field = find_union_type_field(container_type, field->name); + TypeUnionField *type_field = find_union_type_field(union_type, field_name); if (type_field == nullptr) { - ir_add_error_node(ira, field->source_node, + ir_add_error_node(ira, field_source_node, buf_sprintf("no member named '%s' in union '%s'", - buf_ptr(field->name), buf_ptr(&container_type->name))); + buf_ptr(field_name), buf_ptr(&union_type->name))); return ira->codegen->invalid_instruction; } @@ -19493,12 +19508,12 @@ static IrInstruction *ir_analyze_container_init_fields_union(IrAnalyze *ira, IrI } } - bool is_comptime = ir_should_inline(ira->new_irb.exec, instruction->scope) - || type_requires_comptime(ira->codegen, container_type) == ReqCompTimeYes; + bool is_comptime = ir_should_inline(ira->new_irb.exec, source_instruction->scope) + || type_requires_comptime(ira->codegen, union_type) == ReqCompTimeYes; - IrInstruction *result = ir_get_deref(ira, instruction, result_loc, nullptr); + IrInstruction *result = ir_get_deref(ira, source_instruction, result_loc, nullptr); if (is_comptime && !instr_is_comptime(result)) { - ir_add_error(ira, field->result_loc, + ir_add_error(ira, field_result_loc, buf_sprintf("unable to evaluate constant expression")); return ira->codegen->invalid_instruction; } @@ -19511,8 +19526,18 @@ static IrInstruction *ir_analyze_container_init_fields(IrAnalyze *ira, IrInstruc { Error err; if (container_type->id == ZigTypeIdUnion) { - return ir_analyze_container_init_fields_union(ira, instruction, container_type, instr_field_count, - fields, result_loc); + if (instr_field_count != 1) { + ir_add_error(ira, instruction, + buf_sprintf("union initialization expects exactly one field")); + return ira->codegen->invalid_instruction; + } + IrInstructionContainerInitFieldsField *field = &fields[0]; + IrInstruction *field_result_loc = field->result_loc->child; + if (type_is_invalid(field_result_loc->value.type)) + return ira->codegen->invalid_instruction; + + return ir_analyze_union_init(ira, instruction, field->source_node, container_type, field->name, + field_result_loc, result_loc); } if (container_type->id != ZigTypeIdStruct || is_slice(container_type)) { ir_add_error(ira, instruction, @@ -25369,33 +25394,33 @@ static IrInstruction *ir_analyze_instruction_bit_cast_src(IrAnalyze *ira, IrInst return instruction->result_loc_bit_cast->parent->gen_instruction; } -static IrInstruction *ir_analyze_instruction_union_init_2(IrAnalyze *ira, IrInstructionUnionInit2 *union_init_instruction) +static IrInstruction *ir_analyze_instruction_union_init_named_field(IrAnalyze *ira, + IrInstructionUnionInitNamedField *instruction) { - Error err; - IrInstruction *union_type_value = union_init_instruction->union_type_value->child; - ZigType *union_type = ir_resolve_type(ira, union_type_value); - if (type_is_invalid(union_type)) { + ZigType *union_type = ir_resolve_type(ira, instruction->union_type->child); + if (type_is_invalid(union_type)) return ira->codegen->invalid_instruction; - } - if (union_type->id != ZigTypeIdUnion) + if (union_type->id != ZigTypeIdUnion) { + ir_add_error(ira, instruction->union_type, + buf_sprintf("non-union type '%s' passed to @unionInit", buf_ptr(&union_type->name))); return ira->codegen->invalid_instruction; + } - if ((err = ensure_complete_type(ira->codegen, union_type))) + Buf *field_name = ir_resolve_str(ira, instruction->field_name->child); + if (field_name == nullptr) return ira->codegen->invalid_instruction; - IrInstruction *field_name_expr = union_init_instruction->field_name_expr->child; - Buf *field_name = ir_resolve_str(ira, field_name_expr); - if (!field_name) + IrInstruction *field_result_loc = instruction->field_result_loc->child; + if (type_is_invalid(field_result_loc->value.type)) return ira->codegen->invalid_instruction; - IrInstructionContainerInitFieldsField *fields = allocate(1); - - fields[0].name = field_name; - fields[0].value = union_init_instruction->value; - fields[0].source_node = union_init_instruction->base.source_node; + IrInstruction *result_loc = instruction->result_loc->child; + if (type_is_invalid(result_loc->value.type)) + return ira->codegen->invalid_instruction; - return ir_analyze_container_init_fields_union(ira, &union_init_instruction->base, union_type, 1, fields); + return ir_analyze_union_init(ira, &instruction->base, instruction->base.source_node, + union_type, field_name, field_result_loc, result_loc); } static IrInstruction *ir_analyze_instruction_base(IrAnalyze *ira, IrInstruction *instruction) { diff --git a/src/ir_print.cpp b/src/ir_print.cpp index 3ecb7fb683..588a9b2882 100644 --- a/src/ir_print.cpp +++ b/src/ir_print.cpp @@ -1632,7 +1632,9 @@ static void ir_print_union_init_named_field(IrPrint *irp, IrInstructionUnionInit fprintf(irp->f, ", "); ir_print_other_instruction(irp, instruction->field_name); fprintf(irp->f, ", "); - ir_print_other_instruction(irp, instruction->value); + ir_print_other_instruction(irp, instruction->field_result_loc); + fprintf(irp->f, ", "); + ir_print_other_instruction(irp, instruction->result_loc); fprintf(irp->f, ")"); } -- cgit v1.2.3 From a1b952f4b03b7becad85ad47f96a75c0be620cf8 Mon Sep 17 00:00:00 2001 From: emekoi Date: Wed, 3 Jul 2019 13:12:14 -0500 Subject: added tests for #1107 and a note in the reference --- doc/langref.html.in | 6 ++++-- src/ir.cpp | 4 ++-- test/compile_errors.zig | 17 +++++++++++++++++ test/stage1/behavior/switch.zig | 18 ++++++++++++++++++ 4 files changed, 41 insertions(+), 4 deletions(-) (limited to 'src/ir.cpp') diff --git a/doc/langref.html.in b/doc/langref.html.in index 4bd594c113..3b8e77595c 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -2973,6 +2973,7 @@ test "switch on tagged union" { A: u32, C: Point, D, + E: u32, }; var a = Item{ .C = Point{ .x = 1, .y = 2 } }; @@ -2980,8 +2981,9 @@ test "switch on tagged union" { // Switching on more complex enums is allowed. const b = switch (a) { // A capture group is allowed on a match, and will return the enum - // value matched. - Item.A => |item| item, + // value matched. If the payloads of both cases are the same + // they can be put into the same switch prong. + Item.A, Item.E => |item| item, // A reference to the matched value can be obtained using `*` syntax. Item.C => |*item| blk: { diff --git a/src/ir.cpp b/src/ir.cpp index d4cb5f90de..83155da4c1 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -19160,8 +19160,8 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru if (field->type_entry != payload) { if (!invalid_payload) { invalid_payload = ir_add_error(ira, &instruction->base, - buf_sprintf("switch prong contains cases with differing payloads")); - invalid_payload_list = buf_sprintf("types %s", buf_ptr(&field->type_entry->name)); + buf_sprintf("switch prong contains cases with different payloads")); + invalid_payload_list = buf_sprintf("payload types are %s", buf_ptr(&field->type_entry->name)); } if (i == instruction->prongs_len - 1) diff --git a/test/compile_errors.zig b/test/compile_errors.zig index 94cd152eb7..592870c678 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -6048,4 +6048,21 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:5:30: error: expression value is ignored", "tmp.zig:9:30: error: expression value is ignored", ); + + cases.add( + "capture group on switch prong with different payloads", + \\const Union = union(enum) { + \\ A: usize, + \\ B: isize, + \\}; + \\comptime { + \\ var u = Union{ .A = 8 }; + \\ switch (u) { + \\ .A, .B => |e| unreachable, + \\ } + \\} + , + "tmp.zig:8:20: error: switch prong contains cases with different payloads", + "tmp.zig:8:20: note: payload types are usize and isize", + ); } diff --git a/test/stage1/behavior/switch.zig b/test/stage1/behavior/switch.zig index 12e026d0ba..2b7422fa6d 100644 --- a/test/stage1/behavior/switch.zig +++ b/test/stage1/behavior/switch.zig @@ -391,3 +391,21 @@ test "switch with null and T peer types and inferred result location type" { S.doTheTest(1); comptime S.doTheTest(1); } + +test "switch prongs with cases with identical payloads" { + const Union = union(enum) { + A: usize, + B: isize, + C: usize, + }; + const S = struct { + fn doTheTest(u: Union) void { + switch (u) { + .A, .C => |e| expect(@typeOf(e) == usize), + .B => |e| expect(@typeOf(e) == isize), + } + } + }; + S.doTheTest(Union{ .A = 8 }); + comptime S.doTheTest(Union{ .B = -8 }); +} -- cgit v1.2.3 From 96fd1030730e2980fa852ae45a67a2a4008bb163 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Thu, 4 Jul 2019 00:35:28 -0400 Subject: improve the error message and test coverage --- doc/langref.html.in | 2 +- src/ir.cpp | 77 ++++++++++++++++++++--------------------- test/compile_errors.zig | 35 ++++++++++--------- test/stage1/behavior/switch.zig | 28 +++++++++++---- 4 files changed, 79 insertions(+), 63 deletions(-) (limited to 'src/ir.cpp') diff --git a/doc/langref.html.in b/doc/langref.html.in index b006544f00..28d8745a81 100644 --- a/doc/langref.html.in +++ b/doc/langref.html.in @@ -3024,7 +3024,7 @@ test "switch on tagged union" { // Switching on more complex enums is allowed. const b = switch (a) { // A capture group is allowed on a match, and will return the enum - // value matched. If the payloads of both cases are the same + // value matched. If the payload types of both cases are the same // they can be put into the same switch prong. Item.A, Item.E => |item| item, diff --git a/src/ir.cpp b/src/ir.cpp index 995c993ab4..23035fa66d 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -19229,53 +19229,52 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru ZigType *enum_type = target_type->data.unionation.tag_type; assert(enum_type != nullptr); assert(enum_type->id == ZigTypeIdEnum); + assert(instruction->prongs_len > 0); - IrInstruction *prong_value = instruction->prongs_ptr[0]->child; - if (type_is_invalid(prong_value->value.type)) + IrInstruction *first_prong_value = instruction->prongs_ptr[0]->child; + if (type_is_invalid(first_prong_value->value.type)) return ira->codegen->invalid_instruction; - IrInstruction *casted_prong_value = ir_implicit_cast(ira, prong_value, enum_type); - if (type_is_invalid(casted_prong_value->value.type)) + IrInstruction *first_casted_prong_value = ir_implicit_cast(ira, first_prong_value, enum_type); + if (type_is_invalid(first_casted_prong_value->value.type)) return ira->codegen->invalid_instruction; - ConstExprValue *prong_val = ir_resolve_const(ira, casted_prong_value, UndefBad); - if (!prong_val) + ConstExprValue *first_prong_val = ir_resolve_const(ira, first_casted_prong_value, UndefBad); + if (first_prong_val == nullptr) return ira->codegen->invalid_instruction; - TypeUnionField *field = find_union_field_by_tag(target_type, &prong_val->data.x_enum_tag); + TypeUnionField *first_field = find_union_field_by_tag(target_type, &first_prong_val->data.x_enum_tag); - if (instruction->prongs_len != 1) { - ErrorMsg *invalid_payload = nullptr; - Buf *invalid_payload_list = nullptr; - - for (size_t i = 1; i < instruction->prongs_len; i++) { - IrInstruction *casted_prong_value = ir_implicit_cast(ira, instruction->prongs_ptr[i]->child, enum_type); - if (type_is_invalid(casted_prong_value->value.type)) - return ira->codegen->invalid_instruction; - - ConstExprValue *next_prong = ir_resolve_const(ira, casted_prong_value, UndefBad); - if (!next_prong) - return ira->codegen->invalid_instruction; + ErrorMsg *invalid_payload_msg = nullptr; + for (size_t prong_i = 1; prong_i < instruction->prongs_len; prong_i += 1) { + IrInstruction *this_prong_inst = instruction->prongs_ptr[prong_i]->child; + if (type_is_invalid(this_prong_inst->value.type)) + return ira->codegen->invalid_instruction; - ZigType *payload = find_union_field_by_tag(target_type, &next_prong->data.x_enum_tag)->type_entry; + IrInstruction *this_casted_prong_value = ir_implicit_cast(ira, this_prong_inst, enum_type); + if (type_is_invalid(this_casted_prong_value->value.type)) + return ira->codegen->invalid_instruction; - if (field->type_entry != payload) { - if (!invalid_payload) { - invalid_payload = ir_add_error(ira, &instruction->base, - buf_sprintf("switch prong contains cases with different payloads")); - invalid_payload_list = buf_sprintf("payload types are %s", buf_ptr(&field->type_entry->name)); - } + ConstExprValue *this_prong = ir_resolve_const(ira, this_casted_prong_value, UndefBad); + if (this_prong == nullptr) + return ira->codegen->invalid_instruction; - if (i == instruction->prongs_len - 1) - buf_append_buf(invalid_payload_list, buf_sprintf(" and %s", buf_ptr(&payload->name))); - else - buf_append_buf(invalid_payload_list, buf_sprintf(", %s", buf_ptr(&payload->name))); + TypeUnionField *payload_field = find_union_field_by_tag(target_type, &this_prong->data.x_enum_tag); + ZigType *payload_type = payload_field->type_entry; + if (first_field->type_entry != payload_type) { + if (invalid_payload_msg == nullptr) { + invalid_payload_msg = ir_add_error(ira, &instruction->base, + buf_sprintf("capture group with incompatible types")); + add_error_note(ira->codegen, invalid_payload_msg, first_prong_value->source_node, + buf_sprintf("type '%s' here", buf_ptr(&first_field->type_entry->name))); } + add_error_note(ira->codegen, invalid_payload_msg, this_prong_inst->source_node, + buf_sprintf("type '%s' here", buf_ptr(&payload_field->type_entry->name))); } + } - if (invalid_payload) - add_error_note(ira->codegen, invalid_payload, - ((IrInstruction*)instruction)->source_node, invalid_payload_list); + if (invalid_payload_msg != nullptr) { + return ira->codegen->invalid_instruction; } if (instr_is_comptime(target_value_ptr)) { @@ -19288,7 +19287,7 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru return ira->codegen->invalid_instruction; IrInstruction *result = ir_const(ira, &instruction->base, - get_pointer_to_type(ira->codegen, field->type_entry, + get_pointer_to_type(ira->codegen, first_field->type_entry, target_val_ptr->type->data.pointer.is_const)); ConstExprValue *out_val = &result->value; out_val->data.x_ptr.special = ConstPtrSpecialRef; @@ -19298,8 +19297,8 @@ static IrInstruction *ir_analyze_instruction_switch_var(IrAnalyze *ira, IrInstru } IrInstruction *result = ir_build_union_field_ptr(&ira->new_irb, - instruction->base.scope, instruction->base.source_node, target_value_ptr, field, false, false); - result->value.type = get_pointer_to_type(ira->codegen, field->type_entry, + instruction->base.scope, instruction->base.source_node, target_value_ptr, first_field, false, false); + result->value.type = get_pointer_to_type(ira->codegen, first_field->type_entry, target_value_ptr->value.type->data.pointer.is_const); return result; } else if (target_type->id == ZigTypeIdErrorSet) { @@ -23007,11 +23006,11 @@ static IrInstruction *ir_analyze_instruction_mul_add(IrAnalyze *ira, IrInstructi IrInstruction *type_value = instruction->type_value->child; if (type_is_invalid(type_value->value.type)) return ira->codegen->invalid_instruction; - + ZigType *expr_type = ir_resolve_type(ira, type_value); if (type_is_invalid(expr_type)) return ira->codegen->invalid_instruction; - + // Only allow float types, and vectors of floats. ZigType *float_type = (expr_type->id == ZigTypeIdVector) ? expr_type->data.vector.elem_type : expr_type; if (float_type->id != ZigTypeIdFloat) { @@ -25112,7 +25111,7 @@ static IrInstruction *ir_analyze_instruction_float_op(IrAnalyze *ira, IrInstruct IrInstruction *type = instruction->type->child; if (type_is_invalid(type->value.type)) return ira->codegen->invalid_instruction; - + ZigType *expr_type = ir_resolve_type(ira, type); if (type_is_invalid(expr_type)) return ira->codegen->invalid_instruction; diff --git a/test/compile_errors.zig b/test/compile_errors.zig index c6852621e3..df4e38583c 100644 --- a/test/compile_errors.zig +++ b/test/compile_errors.zig @@ -2,6 +2,24 @@ const tests = @import("tests.zig"); const builtin = @import("builtin"); pub fn addCases(cases: *tests.CompileErrorContext) void { + cases.add( + "capture group on switch prong with incompatible payload types", + \\const Union = union(enum) { + \\ A: usize, + \\ B: isize, + \\}; + \\comptime { + \\ var u = Union{ .A = 8 }; + \\ switch (u) { + \\ .A, .B => |e| unreachable, + \\ } + \\} + , + "tmp.zig:8:20: error: capture group with incompatible types", + "tmp.zig:8:9: note: type 'usize' here", + "tmp.zig:8:13: note: type 'isize' here", + ); + cases.add( "wrong type to @hasField", \\export fn entry() bool { @@ -6073,21 +6091,4 @@ pub fn addCases(cases: *tests.CompileErrorContext) void { "tmp.zig:5:30: error: expression value is ignored", "tmp.zig:9:30: error: expression value is ignored", ); - - cases.add( - "capture group on switch prong with different payloads", - \\const Union = union(enum) { - \\ A: usize, - \\ B: isize, - \\}; - \\comptime { - \\ var u = Union{ .A = 8 }; - \\ switch (u) { - \\ .A, .B => |e| unreachable, - \\ } - \\} - , - "tmp.zig:8:20: error: switch prong contains cases with different payloads", - "tmp.zig:8:20: note: payload types are usize and isize", - ); } diff --git a/test/stage1/behavior/switch.zig b/test/stage1/behavior/switch.zig index 2b7422fa6d..806f51b28e 100644 --- a/test/stage1/behavior/switch.zig +++ b/test/stage1/behavior/switch.zig @@ -392,20 +392,36 @@ test "switch with null and T peer types and inferred result location type" { comptime S.doTheTest(1); } -test "switch prongs with cases with identical payloads" { +test "switch prongs with cases with identical payload types" { const Union = union(enum) { A: usize, B: isize, C: usize, }; const S = struct { - fn doTheTest(u: Union) void { + fn doTheTest() void { + doTheSwitch1(Union{ .A = 8 }); + doTheSwitch2(Union{ .B = -8 }); + } + fn doTheSwitch1(u: Union) void { switch (u) { - .A, .C => |e| expect(@typeOf(e) == usize), - .B => |e| expect(@typeOf(e) == isize), + .A, .C => |e| { + expect(@typeOf(e) == usize); + expect(e == 8); + }, + .B => |e| @panic("fail"), + } + } + fn doTheSwitch2(u: Union) void { + switch (u) { + .A, .C => |e| @panic("fail"), + .B => |e| { + expect(@typeOf(e) == isize); + expect(e == -8); + }, } } }; - S.doTheTest(Union{ .A = 8 }); - comptime S.doTheTest(Union{ .B = -8 }); + S.doTheTest(); + comptime S.doTheTest(); } -- cgit v1.2.3 From b118806c69e44029a7af9c9b8bdfa9cdcd280260 Mon Sep 17 00:00:00 2001 From: SamTebbs33 Date: Fri, 5 Jul 2019 00:00:12 +0100 Subject: Add implicit cast for *[N]T to [*c]T --- src/ir.cpp | 4 ++-- test/stage1/behavior/cast.zig | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 23035fa66d..f0ac2f8eaf 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -12773,9 +12773,9 @@ static IrInstruction *ir_analyze_cast(IrAnalyze *ira, IrInstruction *source_inst } } - // *[N]T to [*]T + // *[N]T to [*]T and [*c]T if (wanted_type->id == ZigTypeIdPointer && - wanted_type->data.pointer.ptr_len == PtrLenUnknown && + (wanted_type->data.pointer.ptr_len == PtrLenUnknown || wanted_type->data.pointer.ptr_len == PtrLenC) && actual_type->id == ZigTypeIdPointer && actual_type->data.pointer.ptr_len == PtrLenSingle && actual_type->data.pointer.child_type->id == ZigTypeIdArray) diff --git a/test/stage1/behavior/cast.zig b/test/stage1/behavior/cast.zig index edb0f4ff17..c243f18088 100644 --- a/test/stage1/behavior/cast.zig +++ b/test/stage1/behavior/cast.zig @@ -404,6 +404,16 @@ test "implicit cast from *[N]T to ?[*]T" { expect(std.mem.eql(u16, x.?[0..4], y[0..4])); } +test "implicit cast from *[N]T to [*c]T" { + var x: [4]u16 = [4]u16{ 0, 1, 2, 3 }; + var y: [*c]u16 = &x; + + expect(std.mem.eql(u16, x[0..4], y[0..4])); + x[0] = 8; + y[3] = 6; + expect(std.mem.eql(u16, x[0..4], y[0..4])); +} + test "implicit cast from *T to ?*c_void" { var a: u8 = 1; incrementVoidPtrValue(&a); -- cgit v1.2.3 From fc9e28ea37e0110836d6958c39ffe78ea6cad0f3 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Mon, 8 Jul 2019 14:26:40 -0400 Subject: std.os.getrandom does a libc version check closes #397 --- src/ir.cpp | 2 +- std/c.zig | 27 +++++++++++++++++++++++++++ std/os.zig | 10 +++++++--- 3 files changed, 35 insertions(+), 4 deletions(-) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index f0ac2f8eaf..94307627a1 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -11191,7 +11191,7 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb, } static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) { - assert(!old_bb->suspended); + ir_assert(!old_bb->suspended, old_bb->instruction_list.at(0)); ira->instruction_index = 0; ira->old_irb.current_basic_block = old_bb; ira->const_predecessor_bb = const_predecessor_bb; diff --git a/std/c.zig b/std/c.zig index 029b92e549..693f26008d 100644 --- a/std/c.zig +++ b/std/c.zig @@ -21,6 +21,33 @@ pub fn getErrno(rc: var) u16 { } } +/// The return type is `type` to force comptime function call execution. +/// TODO: https://github.com/ziglang/zig/issues/425 +/// If not linking libc, returns struct{pub const ok = false;} +/// If linking musl libc, returns struct{pub const ok = true;} +/// If linking gnu libc (glibc), the `ok` value will be true if the target +/// version is greater than or equal to `glibc_version`. +/// If linking a libc other than these, returns `false`. +pub fn versionCheck(glibc_version: builtin.Version) type { + return struct { + pub const ok = blk: { + if (!builtin.link_libc) break :blk false; + switch (builtin.abi) { + .musl, .musleabi, .musleabihf => break :blk true, + .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => { + const ver = builtin.glibc_version orelse break :blk false; + if (ver.major < glibc_version.major) break :blk false; + if (ver.major > glibc_version.major) break :blk true; + if (ver.minor < glibc_version.minor) break :blk false; + if (ver.minor > glibc_version.minor) break :blk true; + break :blk ver.patch >= glibc_version.patch; + }, + else => break :blk false, + } + }; + }; +} + // TODO https://github.com/ziglang/zig/issues/265 on this whole file pub extern "c" fn fopen(filename: [*]const u8, modes: [*]const u8) ?*FILE; diff --git a/std/os.zig b/std/os.zig index e9e9c89b4c..1971b51df4 100644 --- a/std/os.zig +++ b/std/os.zig @@ -105,14 +105,18 @@ pub fn getrandom(buf: []u8) GetRandomError!void { } if (linux.is_the_target) { while (true) { - // Bypass libc because it's missing on even relatively new versions. - switch (linux.getErrno(linux.getrandom(buf.ptr, buf.len, 0))) { + const err = if (std.c.versionCheck(builtin.Version{ .major = 2, .minor = 25, .patch = 0 }).ok) blk: { + break :blk errno(std.c.getrandom(buf.ptr, buf.len, 0)); + } else blk: { + break :blk linux.getErrno(linux.getrandom(buf.ptr, buf.len, 0)); + }; + switch (err) { 0 => return, EINVAL => unreachable, EFAULT => unreachable, EINTR => continue, ENOSYS => return getRandomBytesDevURandom(buf), - else => |err| return unexpectedErrno(err), + else => return unexpectedErrno(err), } } } -- cgit v1.2.3 From 67f3bc9101957a414550ea192918da6174a2fcd2 Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 10 Jul 2019 16:17:09 -0400 Subject: mingw: building and linking msvcrt-os.lib --- CMakeLists.txt | 61 +- libc/mingw/include/msvcrt.h | 10 + libc/mingw/lib-common/kernel32.def.in | 1623 +++++++++++++++++++++++++++ libc/mingw/misc/__p___argv.c | 15 + libc/mingw/misc/__p__acmdln.c | 18 + libc/mingw/misc/__p__fmode.c | 17 + libc/mingw/misc/__p__wcmdln.c | 18 + libc/mingw/misc/_configthreadlocale.c | 16 + libc/mingw/misc/_get_current_locale.c | 26 + libc/mingw/misc/invalid_parameter_handler.c | 23 + libc/mingw/misc/lc_locale_func.c | 50 + libc/mingw/misc/onexit_table.c | 77 ++ libc/mingw/misc/output_format.c | 62 + libc/mingw/misc/purecall.c | 18 + libc/mingw/misc/register_tls_atexit.c | 29 + libc/mingw/secapi/_access_s.c | 46 + libc/mingw/secapi/_cgets_s.c | 56 + libc/mingw/secapi/_cgetws_s.c | 56 + libc/mingw/secapi/_chsize_s.c | 46 + libc/mingw/secapi/_controlfp_s.c | 56 + libc/mingw/secapi/_cprintf_s.c | 21 + libc/mingw/secapi/_cprintf_s_l.c | 21 + libc/mingw/secapi/_ctime32_s.c | 56 + libc/mingw/secapi/_ctime64_s.c | 56 + libc/mingw/secapi/_cwprintf_s.c | 21 + libc/mingw/secapi/_cwprintf_s_l.c | 21 + libc/mingw/secapi/_gmtime32_s.c | 51 + libc/mingw/secapi/_gmtime64_s.c | 51 + libc/mingw/secapi/_localtime32_s.c | 51 + libc/mingw/secapi/_localtime64_s.c | 51 + libc/mingw/secapi/_mktemp_s.c | 54 + libc/mingw/secapi/_sopen_s.c | 42 + libc/mingw/secapi/_strdate_s.c | 68 ++ libc/mingw/secapi/_strtime_s.c | 72 ++ libc/mingw/secapi/_umask_s.c | 45 + libc/mingw/secapi/_vcprintf_s.c | 40 + libc/mingw/secapi/_vcprintf_s_l.c | 40 + libc/mingw/secapi/_vcwprintf_s.c | 40 + libc/mingw/secapi/_vcwprintf_s_l.c | 40 + libc/mingw/secapi/_vscprintf_p.c | 9 + libc/mingw/secapi/_vscwprintf_p.c | 9 + libc/mingw/secapi/_vswprintf_p.c | 9 + libc/mingw/secapi/_waccess_s.c | 47 + libc/mingw/secapi/_wasctime_s.c | 52 + libc/mingw/secapi/_wctime32_s.c | 56 + libc/mingw/secapi/_wctime64_s.c | 56 + libc/mingw/secapi/_wmktemp_s.c | 55 + libc/mingw/secapi/_wstrdate_s.c | 68 ++ libc/mingw/secapi/_wstrtime_s.c | 71 ++ libc/mingw/secapi/asctime_s.c | 52 + libc/mingw/secapi/memcpy_s.c | 59 + libc/mingw/secapi/memmove_s.c | 60 + libc/mingw/secapi/rand_s.c | 30 + libc/mingw/secapi/sprintf_s.c | 20 + libc/mingw/secapi/strerror_s.c | 53 + libc/mingw/secapi/vsprintf_s.c | 41 + libc/mingw/secapi/wmemcpy_s.c | 61 + libc/mingw/secapi/wmemmove_s.c | 61 + libc/mingw/stdio/acrt_iob_func.c | 15 + libc/mingw/stdio/mingw_lock.c | 102 ++ src/ir.cpp | 3 +- src/link.cpp | 111 ++ std/special/compiler_rt.zig | 21 + 63 files changed, 4282 insertions(+), 3 deletions(-) create mode 100644 libc/mingw/include/msvcrt.h create mode 100644 libc/mingw/lib-common/kernel32.def.in create mode 100644 libc/mingw/misc/__p___argv.c create mode 100644 libc/mingw/misc/__p__acmdln.c create mode 100644 libc/mingw/misc/__p__fmode.c create mode 100644 libc/mingw/misc/__p__wcmdln.c create mode 100644 libc/mingw/misc/_configthreadlocale.c create mode 100644 libc/mingw/misc/_get_current_locale.c create mode 100644 libc/mingw/misc/invalid_parameter_handler.c create mode 100644 libc/mingw/misc/lc_locale_func.c create mode 100644 libc/mingw/misc/onexit_table.c create mode 100644 libc/mingw/misc/output_format.c create mode 100644 libc/mingw/misc/purecall.c create mode 100644 libc/mingw/misc/register_tls_atexit.c create mode 100644 libc/mingw/secapi/_access_s.c create mode 100644 libc/mingw/secapi/_cgets_s.c create mode 100644 libc/mingw/secapi/_cgetws_s.c create mode 100644 libc/mingw/secapi/_chsize_s.c create mode 100644 libc/mingw/secapi/_controlfp_s.c create mode 100644 libc/mingw/secapi/_cprintf_s.c create mode 100644 libc/mingw/secapi/_cprintf_s_l.c create mode 100644 libc/mingw/secapi/_ctime32_s.c create mode 100644 libc/mingw/secapi/_ctime64_s.c create mode 100644 libc/mingw/secapi/_cwprintf_s.c create mode 100644 libc/mingw/secapi/_cwprintf_s_l.c create mode 100644 libc/mingw/secapi/_gmtime32_s.c create mode 100644 libc/mingw/secapi/_gmtime64_s.c create mode 100644 libc/mingw/secapi/_localtime32_s.c create mode 100644 libc/mingw/secapi/_localtime64_s.c create mode 100644 libc/mingw/secapi/_mktemp_s.c create mode 100644 libc/mingw/secapi/_sopen_s.c create mode 100644 libc/mingw/secapi/_strdate_s.c create mode 100644 libc/mingw/secapi/_strtime_s.c create mode 100644 libc/mingw/secapi/_umask_s.c create mode 100644 libc/mingw/secapi/_vcprintf_s.c create mode 100644 libc/mingw/secapi/_vcprintf_s_l.c create mode 100644 libc/mingw/secapi/_vcwprintf_s.c create mode 100644 libc/mingw/secapi/_vcwprintf_s_l.c create mode 100644 libc/mingw/secapi/_vscprintf_p.c create mode 100644 libc/mingw/secapi/_vscwprintf_p.c create mode 100644 libc/mingw/secapi/_vswprintf_p.c create mode 100644 libc/mingw/secapi/_waccess_s.c create mode 100644 libc/mingw/secapi/_wasctime_s.c create mode 100644 libc/mingw/secapi/_wctime32_s.c create mode 100644 libc/mingw/secapi/_wctime64_s.c create mode 100644 libc/mingw/secapi/_wmktemp_s.c create mode 100644 libc/mingw/secapi/_wstrdate_s.c create mode 100644 libc/mingw/secapi/_wstrtime_s.c create mode 100644 libc/mingw/secapi/asctime_s.c create mode 100644 libc/mingw/secapi/memcpy_s.c create mode 100644 libc/mingw/secapi/memmove_s.c create mode 100644 libc/mingw/secapi/rand_s.c create mode 100644 libc/mingw/secapi/sprintf_s.c create mode 100644 libc/mingw/secapi/strerror_s.c create mode 100644 libc/mingw/secapi/vsprintf_s.c create mode 100644 libc/mingw/secapi/wmemcpy_s.c create mode 100644 libc/mingw/secapi/wmemmove_s.c create mode 100644 libc/mingw/stdio/acrt_iob_func.c create mode 100644 libc/mingw/stdio/mingw_lock.c (limited to 'src/ir.cpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index 3897c74912..f2bfb61b5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7613,15 +7613,72 @@ set(ZIG_LIBC_FILES "mingw/crt/xncommod.c" "mingw/crt/xthdloc.c" "mingw/crt/xtxtmode.c" - "mingw/def-include/.func.def.in.swp" - "mingw/def-include/.msvcrt-common.def.in.swp" "mingw/def-include/func.def.in" "mingw/def-include/msvcrt-common.def.in" "mingw/include/config.h" "mingw/include/internal.h" + "mingw/include/msvcrt.h" "mingw/include/oscalls.h" "mingw/include/sect_attribs.h" + "mingw/lib-common/kernel32.def.in" "mingw/lib-common/msvcrt.def.in" + "mingw/misc/__p___argv.c" + "mingw/misc/__p__acmdln.c" + "mingw/misc/__p__fmode.c" + "mingw/misc/__p__wcmdln.c" + "mingw/misc/_configthreadlocale.c" + "mingw/misc/_get_current_locale.c" + "mingw/misc/invalid_parameter_handler.c" + "mingw/misc/lc_locale_func.c" + "mingw/misc/onexit_table.c" + "mingw/misc/output_format.c" + "mingw/misc/purecall.c" + "mingw/misc/register_tls_atexit.c" + "mingw/secapi/_access_s.c" + "mingw/secapi/_cgets_s.c" + "mingw/secapi/_cgetws_s.c" + "mingw/secapi/_chsize_s.c" + "mingw/secapi/_controlfp_s.c" + "mingw/secapi/_cprintf_s.c" + "mingw/secapi/_cprintf_s_l.c" + "mingw/secapi/_ctime32_s.c" + "mingw/secapi/_ctime64_s.c" + "mingw/secapi/_cwprintf_s.c" + "mingw/secapi/_cwprintf_s_l.c" + "mingw/secapi/_gmtime32_s.c" + "mingw/secapi/_gmtime64_s.c" + "mingw/secapi/_localtime32_s.c" + "mingw/secapi/_localtime64_s.c" + "mingw/secapi/_mktemp_s.c" + "mingw/secapi/_sopen_s.c" + "mingw/secapi/_strdate_s.c" + "mingw/secapi/_strtime_s.c" + "mingw/secapi/_umask_s.c" + "mingw/secapi/_vcprintf_s.c" + "mingw/secapi/_vcprintf_s_l.c" + "mingw/secapi/_vcwprintf_s.c" + "mingw/secapi/_vcwprintf_s_l.c" + "mingw/secapi/_vscprintf_p.c" + "mingw/secapi/_vscwprintf_p.c" + "mingw/secapi/_vswprintf_p.c" + "mingw/secapi/_waccess_s.c" + "mingw/secapi/_wasctime_s.c" + "mingw/secapi/_wctime32_s.c" + "mingw/secapi/_wctime64_s.c" + "mingw/secapi/_wmktemp_s.c" + "mingw/secapi/_wstrdate_s.c" + "mingw/secapi/_wstrtime_s.c" + "mingw/secapi/asctime_s.c" + "mingw/secapi/memcpy_s.c" + "mingw/secapi/memmove_s.c" + "mingw/secapi/rand_s.c" + "mingw/secapi/sprintf_s.c" + "mingw/secapi/strerror_s.c" + "mingw/secapi/vsprintf_s.c" + "mingw/secapi/wmemcpy_s.c" + "mingw/secapi/wmemmove_s.c" + "mingw/stdio/acrt_iob_func.c" + "mingw/stdio/mingw_lock.c" "musl/arch/aarch64/atomic_arch.h" "musl/arch/aarch64/bits/alltypes.h.in" "musl/arch/aarch64/bits/endian.h" diff --git a/libc/mingw/include/msvcrt.h b/libc/mingw/include/msvcrt.h new file mode 100644 index 0000000000..d5346254f0 --- /dev/null +++ b/libc/mingw/include/msvcrt.h @@ -0,0 +1,10 @@ +#include + +#ifndef __LIBMSVCRT__ +#error "This file should only be used in libmsvcrt.a" +#endif + +static inline HANDLE __mingw_get_msvcrt_handle(void) +{ + return GetModuleHandleW(L"msvcrt.dll"); +} diff --git a/libc/mingw/lib-common/kernel32.def.in b/libc/mingw/lib-common/kernel32.def.in new file mode 100644 index 0000000000..3a556294c6 --- /dev/null +++ b/libc/mingw/lib-common/kernel32.def.in @@ -0,0 +1,1623 @@ +#include "func.def.in" + +LIBRARY "KERNEL32.dll" +EXPORTS +AcquireSRWLockExclusive +AcquireSRWLockShared +ActivateActCtx +ActivateActCtxWorker +AddAtomA +AddAtomW +AddConsoleAliasA +AddConsoleAliasW +AddDllDirectory +AddIntegrityLabelToBoundaryDescriptor +AddLocalAlternateComputerNameA +AddLocalAlternateComputerNameW +AddRefActCtx +AddRefActCtxWorker +AddResourceAttributeAce +AddSIDToBoundaryDescriptor +AddScopedPolicyIDAce +AddSecureMemoryCacheCallback +AddVectoredContinueHandler +AddVectoredExceptionHandler +AdjustCalendarDate +AllocConsole +AllocateUserPhysicalPages +AllocateUserPhysicalPagesNuma +AppXGetOSMaxVersionTested +ApplicationRecoveryFinished +ApplicationRecoveryInProgress +AreFileApisANSI +AssignProcessToJobObject +AttachConsole +BackupRead +BackupSeek +BackupWrite +BaseCheckAppcompatCache +BaseCheckAppcompatCacheEx +BaseCheckAppcompatCacheExWorker +BaseCheckAppcompatCacheWorker +BaseCheckElevation +BaseCheckRunApp +BaseCleanupAppcompatCacheSupport +BaseCleanupAppcompatCacheSupportWorker +BaseDestroyVDMEnvironment +BaseDllReadWriteIniFile +BaseDumpAppcompatCache +BaseDumpAppcompatCacheWorker +BaseElevationPostProcessing +BaseFlushAppcompatCache +BaseFlushAppcompatCacheWorker +BaseFormatObjectAttributes +BaseFormatTimeOut +BaseFreeAppCompatDataForProcessWorker +BaseGenerateAppCompatData +BaseGetNamedObjectDirectory +BaseInitAppcompatCacheSupport +BaseInitAppcompatCacheSupportWorker +BaseIsAppcompatInfrastructureDisabled +BaseIsAppcompatInfrastructureDisabledWorker +BaseIsDosApplication +BaseProcessInitPostImport +BaseProcessStart +BaseQueryModuleData +BaseReadAppCompatDataForProcessWorker +BaseThreadStart +BaseSetLastNTError +BaseThreadInitThunk +BaseUpdateAppcompatCache +BaseUpdateAppcompatCacheWorker +BaseUpdateVDMEntry +BaseVerifyUnicodeString +BaseWriteErrorElevationRequiredEvent +Basep8BitStringToDynamicUnicodeString +BasepAllocateActivationContextActivationBlock +BasepAnsiStringToDynamicUnicodeString +BasepAppContainerEnvironmentExtension +BasepAppXExtension +BasepCheckAppCompat +BasepCheckBadapp +BasepCheckWebBladeHashes +BasepCheckWinSaferRestrictions +BasepConstructSxsCreateProcessMessage +BasepCopyEncryption +BasepFreeActivationContextActivationBlock +BasepFreeAppCompatData +BasepGetAppCompatData +BasepGetComputerNameFromNtPath +BasepGetExeArchType +BasepIsProcessAllowed +BasepMapModuleHandle +BasepNotifyLoadStringResource +BasepPostSuccessAppXExtension +BasepProcessInvalidImage +BasepQueryAppCompat +BasepReleaseAppXContext +BasepReleaseSxsCreateProcessUtilityStruct +BasepReportFault +BasepSetFileEncryptionCompression +Beep +BeginUpdateResourceA +BeginUpdateResourceW +BindIoCompletionCallback +BuildCommDCBA +BuildCommDCBAndTimeoutsA +BuildCommDCBAndTimeoutsW +BuildCommDCBW +CallNamedPipeA +CallNamedPipeW +CallbackMayRunLong +CalloutOnFiberStack +CancelDeviceWakeupRequest +CancelIo +CancelIoEx +CancelSynchronousIo +CancelThreadpoolIo +CancelTimerQueueTimer +CancelWaitableTimer +CeipIsOptedIn +ChangeTimerQueueTimer +CheckAllowDecryptedRemoteDestinationPolicy +CheckElevation +CheckElevationEnabled +CheckForReadOnlyResource +CheckForReadOnlyResourceFilter +CheckNameLegalDOS8Dot3A +CheckNameLegalDOS8Dot3W +CheckRemoteDebuggerPresent +CheckTokenCapability +CheckTokenMembershipEx +ClearCommBreak +ClearCommError +CloseConsoleHandle +CloseHandle +ClosePackageInfo +ClosePrivateNamespace +CloseProfileUserMapping +CloseState +CloseThreadpool +CloseThreadpoolCleanupGroup +CloseThreadpoolCleanupGroupMembers +CloseThreadpoolIo +CloseThreadpoolTimer +CloseThreadpoolWait +CloseThreadpoolWork +CmdBatNotification +CommConfigDialogA +CommConfigDialogW +CompareCalendarDates +CompareFileTime +CompareStringA +CompareStringEx +CompareStringOrdinal +CompareStringW +ConnectNamedPipe +ConsoleIMERoutine +ConsoleMenuControl +ContinueDebugEvent +ConvertCalDateTimeToSystemTime +ConvertDefaultLocale +ConvertFiberToThread +ConvertNLSDayOfWeekToWin32DayOfWeek +ConvertSystemTimeToCalDateTime +ConvertThreadToFiber +ConvertThreadToFiberEx +CopyContext +CopyExtendedContext +CopyFile2 +CopyFileA +CopyFileExA +CopyFileExW +CopyFileTransactedA +CopyFileTransactedW +CopyFileW +CopyLZFile +CreateActCtxA +CreateActCtxW +CreateActCtxWWorker +CreateBoundaryDescriptorA +CreateBoundaryDescriptorW +CreateConsoleScreenBuffer +CreateDirectoryA +CreateDirectoryExA +CreateDirectoryExW +CreateDirectoryTransactedA +CreateDirectoryTransactedW +CreateDirectoryW +CreateEventA +CreateEventExA +CreateEventExW +CreateEventW +CreateFiber +CreateFiberEx +CreateFile2 +CreateFileA +CreateFileMappingA +CreateFileMappingFromApp +CreateFileMappingNumaA +CreateFileMappingNumaW +CreateFileMappingW +CreateFileTransactedA +CreateFileTransactedW +CreateFileW +CreateHardLinkA +CreateHardLinkTransactedA +CreateHardLinkTransactedW +CreateHardLinkW +CreateIoCompletionPort +CreateJobObjectA +CreateJobObjectW +CreateJobSet +CreateMailslotA +CreateMailslotW +CreateMemoryResourceNotification +CreateMutexA +CreateMutexExA +CreateMutexExW +CreateMutexW +CreateNamedPipeA +CreateNamedPipeW +CreateNlsSecurityDescriptor +CreatePipe +CreatePrivateNamespaceA +CreatePrivateNamespaceW +CreateProcessA +CreateProcessAsUserW +CreateProcessInternalA +CreateProcessInternalW +CreateProcessW +CreateRemoteThread +CreateRemoteThreadEx +CreateSemaphoreA +CreateSemaphoreExA +CreateSemaphoreExW +CreateSemaphoreW +CreateSymbolicLinkA +CreateSymbolicLinkTransactedA +CreateSymbolicLinkTransactedW +CreateSymbolicLinkW +CreateTapePartition +CreateThread +CreateThreadpool +CreateThreadpoolCleanupGroup +CreateThreadpoolIo +CreateThreadpoolTimer +CreateThreadpoolWait +CreateThreadpoolWork +CreateTimerQueue +CreateTimerQueueTimer +CreateToolhelp32Snapshot +F_X64(CreateUmsCompletionList) +F_X64(CreateUmsThreadContext) +CreateWaitableTimerA +CreateWaitableTimerExA +CreateWaitableTimerExW +CreateWaitableTimerW +CtrlRoutine +DeactivateActCtx +DeactivateActCtxWorker +DebugActiveProcess +DebugActiveProcessStop +DebugBreak +DebugBreakProcess +DebugSetProcessKillOnExit +DecodePointer +DecodeSystemPointer +DefineDosDeviceA +DefineDosDeviceW +DelayLoadFailureHook +DeleteAtom +DeleteBoundaryDescriptor +DeleteCriticalSection +DeleteFiber +DeleteFileA +DeleteFileTransactedA +DeleteFileTransactedW +DeleteFileW +DeleteProcThreadAttributeList +DeleteSynchronizationBarrier +DeleteTimerQueue +DeleteTimerQueueEx +DeleteTimerQueueTimer +F_X64(DeleteUmsCompletionList) +F_X64(DeleteUmsThreadContext) +DeleteVolumeMountPointA +DeleteVolumeMountPointW +F_X64(DequeueUmsCompletionListItems) +DeviceIoControl +DisableThreadLibraryCalls +DisableThreadProfiling +DisassociateCurrentThreadFromCallback +DiscardVirtualMemory +DisconnectNamedPipe +DnsHostnameToComputerNameA +DnsHostnameToComputerNameExW +DnsHostnameToComputerNameW +DosDateTimeToFileTime +DosPathToSessionPathA +DosPathToSessionPathW +DuplicateConsoleHandle +DuplicateEncryptionInfoFileExt +DuplicateHandle +EnableThreadProfiling +EncodePointer +EncodeSystemPointer +EndUpdateResourceA +EndUpdateResourceW +EnterCriticalSection +F_X64(EnterUmsSchedulingMode) +EnterSynchronizationBarrier +EnumCalendarInfoA +EnumCalendarInfoExA +EnumCalendarInfoExEx +EnumCalendarInfoExW +EnumCalendarInfoW +EnumDateFormatsA +EnumDateFormatsExA +EnumDateFormatsExEx +EnumDateFormatsExW +EnumDateFormatsW +EnumLanguageGroupLocalesA +EnumLanguageGroupLocalesW +EnumResourceLanguagesA +EnumResourceLanguagesExA +EnumResourceLanguagesExW +EnumResourceLanguagesW +EnumResourceNamesA +EnumResourceNamesExA +EnumResourceNamesExW +EnumResourceNamesW +EnumResourceTypesA +EnumResourceTypesExA +EnumResourceTypesExW +EnumResourceTypesW +EnumSystemCodePagesA +EnumSystemCodePagesW +EnumSystemFirmwareTables +EnumSystemGeoID +EnumSystemLanguageGroupsA +EnumSystemLanguageGroupsW +EnumSystemLocalesA +EnumSystemLocalesEx +EnumSystemLocalesW +EnumTimeFormatsA +EnumTimeFormatsEx +EnumTimeFormatsW +EnumUILanguagesA +EnumUILanguagesW +EnumerateLocalComputerNamesA +EnumerateLocalComputerNamesW +EraseTape +EscapeCommFunction +F_X64(ExecuteUmsThread) +ExitProcess +ExitThread +ExitVDM +ExpandEnvironmentStringsA +ExpandEnvironmentStringsW +ExpungeConsoleCommandHistoryA +ExpungeConsoleCommandHistoryW +FatalAppExitA +FatalAppExitW +FatalExit +FileTimeToDosDateTime +FileTimeToLocalFileTime +FileTimeToSystemTime +FillConsoleOutputAttribute +FillConsoleOutputCharacterA +FillConsoleOutputCharacterW +FindActCtxSectionGuid +FindActCtxSectionGuidWorker +FindActCtxSectionStringA +FindActCtxSectionStringW +FindActCtxSectionStringWWorker +FindAtomA +FindAtomW +FindClose +FindCloseChangeNotification +FindFirstChangeNotificationA +FindFirstChangeNotificationW +FindFirstFileA +FindFirstFileExA +FindFirstFileExW +FindFirstFileNameTransactedW +FindFirstFileNameW +FindFirstFileTransactedA +FindFirstFileTransactedW +FindFirstFileW +FindFirstStreamTransactedW +FindFirstStreamW +FindFirstVolumeA +FindFirstVolumeMountPointA +FindFirstVolumeMountPointW +FindFirstVolumeW +FindNLSString +FindNLSStringEx +FindNextChangeNotification +FindNextFileA +FindNextFileNameW +FindNextFileW +FindNextStreamW +FindNextVolumeA +FindNextVolumeMountPointA +FindNextVolumeMountPointW +FindNextVolumeW +FindPackagesByPackageFamily +FindResourceA +FindResourceExA +FindResourceExW +FindResourceW +FindStringOrdinal +FindVolumeClose +FindVolumeMountPointClose +FlsAlloc +FlsFree +FlsGetValue +FlsSetValue +FlushConsoleInputBuffer +FlushFileBuffers +FlushInstructionCache +FlushProcessWriteBuffers +FlushViewOfFile +FoldStringA +FoldStringW +FormatApplicationUserModelId +FormatMessageA +FormatMessageW +FreeConsole +FreeEnvironmentStringsA +FreeEnvironmentStringsW +FreeLibrary +FreeLibraryAndExitThread +FreeLibraryWhenCallbackReturns +FreeResource +FreeUserPhysicalPages +GenerateConsoleCtrlEvent +GetACP +GetActiveProcessorCount +GetActiveProcessorGroupCount +GetAppContainerAce +GetAppContainerNamedObjectPath +GetApplicationRecoveryCallback +GetApplicationRecoveryCallbackWorker +GetApplicationRestartSettings +GetApplicationRestartSettingsWorker +GetApplicationUserModelId +GetAtomNameA +GetAtomNameW +GetBinaryType +GetBinaryTypeA +GetBinaryTypeW +GetCPFileNameFromRegistry +GetCPInfo +GetCPInfoExA +GetCPInfoExW +GetCachedSigningLevel +GetCalendarDateFormat +GetCalendarDateFormatEx +GetCalendarDaysInMonth +GetCalendarDifferenceInDays +GetCalendarInfoA +GetCalendarInfoEx +GetCalendarInfoW +GetCalendarMonthsInYear +GetCalendarSupportedDateRange +GetCalendarWeekNumber +GetComPlusPackageInstallStatus +GetCommConfig +GetCommMask +GetCommModemStatus +GetCommProperties +GetCommState +GetCommTimeouts +GetCommandLineA +GetCommandLineW +GetCompressedFileSizeA +GetCompressedFileSizeTransactedA +GetCompressedFileSizeTransactedW +GetCompressedFileSizeW +GetComputerNameA +GetComputerNameExA +GetComputerNameExW +GetComputerNameW +GetConsoleAliasA +GetConsoleAliasExesA +GetConsoleAliasExesLengthA +GetConsoleAliasExesLengthW +GetConsoleAliasExesW +GetConsoleAliasW +GetConsoleAliasesA +GetConsoleAliasesLengthA +GetConsoleAliasesLengthW +GetConsoleAliasesW +GetConsoleCP +GetConsoleCharType +GetConsoleCommandHistoryA +GetConsoleCommandHistoryLengthA +GetConsoleCommandHistoryLengthW +GetConsoleCommandHistoryW +GetConsoleCursorInfo +GetConsoleCursorMode +GetConsoleDisplayMode +GetConsoleFontInfo +GetConsoleFontSize +GetConsoleHardwareState +GetConsoleHistoryInfo +GetConsoleInputExeNameA +GetConsoleInputExeNameW +GetConsoleInputWaitHandle +GetConsoleKeyboardLayoutNameA +GetConsoleKeyboardLayoutNameW +GetConsoleMode +GetConsoleNlsMode +GetConsoleOriginalTitleA +GetConsoleOriginalTitleW +GetConsoleOutputCP +GetConsoleProcessList +GetConsoleScreenBufferInfo +GetConsoleScreenBufferInfoEx +GetConsoleSelectionInfo +GetConsoleTitleA +GetConsoleTitleW +GetConsoleWindow +GetCurrencyFormatA +GetCurrencyFormatEx +GetCurrencyFormatW +GetCurrentActCtx +GetCurrentActCtxWorker +GetCurrentApplicationUserModelId +GetCurrentConsoleFont +GetCurrentConsoleFontEx +GetCurrentDirectoryA +GetCurrentDirectoryW +GetCurrentPackageFamilyName +GetCurrentPackageFullName +GetCurrentPackageId +GetCurrentPackageInfo +GetCurrentPackagePath +GetCurrentProcess +GetCurrentProcessId +GetCurrentProcessorNumber +GetCurrentProcessorNumberEx +GetCurrentThread +GetCurrentThreadId +GetCurrentThreadStackLimits +F_X64(GetCurrentUmsThread) +GetDateFormatA +GetDateFormatAWorker +GetDateFormatEx +GetDateFormatW +GetDateFormatWWorker +GetDefaultCommConfigA +GetDefaultCommConfigW +GetDefaultSortkeySize +GetDevicePowerState +GetDiskFreeSpaceA +GetDiskFreeSpaceExA +GetDiskFreeSpaceExW +GetDiskFreeSpaceW +GetDllDirectoryA +GetDllDirectoryW +GetDriveTypeA +GetDriveTypeW +GetDurationFormat +GetDurationFormatEx +GetDynamicTimeZoneInformation +GetEnabledExtendedFeatures +GetEncryptedFileVersionExt +GetEnvironmentStrings +GetEnvironmentStringsA +GetEnvironmentStringsW +GetEnvironmentVariableA +GetEnvironmentVariableW +GetEraNameCountedString +GetErrorMode +GetExitCodeProcess +GetExitCodeThread +GetExpandedNameA +GetExpandedNameW +GetExtendedContextLength +GetExtendedFeaturesMask +GetFileAttributesA +GetFileAttributesExA +GetFileAttributesExW +GetFileAttributesTransactedA +GetFileAttributesTransactedW +GetFileAttributesW +GetFileBandwidthReservation +GetFileInformationByHandle +GetFileInformationByHandleEx +GetFileMUIInfo +GetFileMUIPath +GetFileSize +GetFileSizeEx +GetFileTime +GetFileType +GetFinalPathNameByHandleA +GetFinalPathNameByHandleW +GetFirmwareEnvironmentVariableA +GetFirmwareEnvironmentVariableExA +GetFirmwareEnvironmentVariableExW +GetFirmwareEnvironmentVariableW +GetFirmwareType +GetFullPathNameA +GetFullPathNameTransactedA +GetFullPathNameTransactedW +GetFullPathNameW +GetGeoInfoA +GetGeoInfoW +GetHandleInformation +GetLargePageMinimum +GetLargestConsoleWindowSize +GetLastError +GetLinguistLangSize +GetLocalTime +GetLocaleInfoA +GetLocaleInfoEx +GetLocaleInfoW +GetLogicalDriveStringsA +GetLogicalDriveStringsW +GetLogicalDrives +GetLogicalProcessorInformation +GetLogicalProcessorInformationEx +GetLongPathNameA +GetLongPathNameTransactedA +GetLongPathNameTransactedW +GetLongPathNameW +GetMailslotInfo +GetMaximumProcessorCount +GetMaximumProcessorGroupCount +GetMemoryErrorHandlingCapabilities +GetModuleFileNameA +GetModuleFileNameW +GetModuleHandleA +GetModuleHandleExA +GetModuleHandleExW +GetModuleHandleW +GetNLSVersion +GetNLSVersionEx +GetNamedPipeAttribute +GetNamedPipeClientComputerNameA +GetNamedPipeClientComputerNameW +GetNamedPipeClientProcessId +GetNamedPipeClientSessionId +GetNamedPipeHandleStateA +GetNamedPipeHandleStateW +GetNamedPipeInfo +GetNamedPipeServerProcessId +GetNamedPipeServerSessionId +GetNativeSystemInfo +F_X64(GetNextUmsListItem) +GetNextVDMCommand +GetNlsSectionName +GetNumaAvailableMemoryNode +GetNumaAvailableMemoryNodeEx +GetNumaHighestNodeNumber +GetNumaNodeNumberFromHandle +GetNumaNodeProcessorMask +GetNumaNodeProcessorMaskEx +GetNumaProcessorNode +GetNumaProcessorNodeEx +GetNumaProximityNode +GetNumaProximityNodeEx +GetNumberFormatA +GetNumberFormatEx +GetNumberFormatW +GetNumberOfConsoleFonts +GetNumberOfConsoleInputEvents +GetNumberOfConsoleMouseButtons +GetOEMCP +GetOverlappedResult +GetOverlappedResultEx +GetPackageApplicationIds +GetPackageFamilyName +GetPackageFullName +GetPackageId +GetPackageInfo +GetPackagePath +GetPackagePathByFullName +GetPackagesByPackageFamily +GetPhysicallyInstalledSystemMemory +GetPriorityClass +GetPrivateProfileIntA +GetPrivateProfileIntW +GetPrivateProfileSectionA +GetPrivateProfileSectionNamesA +GetPrivateProfileSectionNamesW +GetPrivateProfileSectionW +GetPrivateProfileStringA +GetPrivateProfileStringW +GetPrivateProfileStructA +GetPrivateProfileStructW +GetProcAddress +GetProcessAffinityMask +GetProcessDEPPolicy +GetProcessGroupAffinity +GetProcessHandleCount +GetProcessHeap +GetProcessHeaps +GetProcessId +GetProcessIdOfThread +GetProcessInformation +GetProcessIoCounters +GetProcessMitigationPolicy +GetProcessPreferredUILanguages +GetProcessPriorityBoost +GetProcessShutdownParameters +GetProcessTimes +GetProcessVersion +GetProcessWorkingSetSize +GetProcessWorkingSetSizeEx +GetProcessorSystemCycleTime +GetProductInfo +GetProfileIntA +GetProfileIntW +GetProfileSectionA +GetProfileSectionW +GetProfileStringA +GetProfileStringW +GetQueuedCompletionStatus +GetQueuedCompletionStatusEx +GetShortPathNameA +GetShortPathNameW +GetStagedPackagePathByFullName +GetStartupInfoA +GetStartupInfoW +GetStateFolder +GetStdHandle +GetStringScripts +GetStringTypeA +GetStringTypeExA +GetStringTypeExW +GetStringTypeW +GetSystemAppDataKey +GetSystemDEPPolicy +GetSystemDefaultLCID +GetSystemDefaultLangID +GetSystemDefaultLocaleName +GetSystemDefaultUILanguage +GetSystemDirectoryA +GetSystemDirectoryW +GetSystemFileCacheSize +GetSystemFirmwareTable +GetSystemInfo +GetSystemPowerStatus +GetSystemPreferredUILanguages +GetSystemRegistryQuota +GetSystemTime +GetSystemTimeAdjustment +GetSystemTimeAsFileTime +GetSystemTimePreciseAsFileTime +GetSystemTimes +GetSystemWindowsDirectoryA +GetSystemWindowsDirectoryW +GetSystemWow64DirectoryA +GetSystemWow64DirectoryW +GetTapeParameters +GetTapePosition +GetTapeStatus +GetTempFileNameA +GetTempFileNameW +GetTempPathA +GetTempPathW +GetThreadContext +GetThreadErrorMode +GetThreadGroupAffinity +GetThreadIOPendingFlag +GetThreadId +GetThreadIdealProcessorEx +GetThreadInformation +GetThreadLocale +GetThreadPreferredUILanguages +GetThreadPriority +GetThreadPriorityBoost +GetThreadSelectorEntry +GetThreadTimes +GetThreadUILanguage +GetTickCount +GetTickCount64 +GetTimeFormatA +GetTimeFormatAWorker +GetTimeFormatEx +GetTimeFormatW +GetTimeFormatWWorker +GetTimeZoneInformation +GetTimeZoneInformationForYear +GetUILanguageInfo +F_X64(GetUmsCompletionListEvent) +GetUserDefaultLCID +GetUserDefaultLangID +GetUserDefaultLocaleName +GetUserDefaultUILanguage +GetUserGeoID +GetUserPreferredUILanguages +GetVDMCurrentDirectories +GetVersion +GetVersionExA +GetVersionExW +GetVolumeInformationA +GetVolumeInformationByHandleW +GetVolumeInformationW +GetVolumeNameForVolumeMountPointA +GetVolumeNameForVolumeMountPointW +GetVolumePathNameA +GetVolumePathNameW +GetVolumePathNamesForVolumeNameA +GetVolumePathNamesForVolumeNameW +GetWindowsDirectoryA +GetWindowsDirectoryW +GetWriteWatch +GlobalAddAtomA +GlobalAddAtomExA +GlobalAddAtomExW +GlobalAddAtomW +GlobalAlloc +GlobalCompact +GlobalDeleteAtom +GlobalFindAtomA +GlobalFindAtomW +GlobalFix +GlobalFlags +GlobalFree +GlobalGetAtomNameA +GlobalGetAtomNameW +GlobalHandle +GlobalLock +GlobalMemoryStatus +GlobalMemoryStatusEx +GlobalReAlloc +GlobalSize +GlobalUnWire +GlobalUnfix +GlobalUnlock +GlobalWire +Heap32First +Heap32ListFirst +Heap32ListNext +Heap32Next +HeapAlloc +HeapCompact +HeapCreate +HeapCreateTagsW +HeapDestroy +HeapExtend +HeapFree +HeapLock +HeapQueryInformation +HeapQueryTagW +HeapReAlloc +HeapSetInformation +HeapSize +HeapSummary +HeapUnlock +HeapUsage +HeapValidate +HeapWalk +IdnToAscii +IdnToNameprepUnicode +IdnToUnicode +InitAtomTable +InitializeConditionVariable +InitializeCriticalSection +InitOnceBeginInitialize +InitOnceComplete +InitOnceExecuteOnce +InitOnceInitialize +InitializeConditionVariable +InitializeContext +InitializeCriticalSection +InitializeCriticalSectionAndSpinCount +InitializeCriticalSectionEx +InitializeExtendedContext +InitializeProcThreadAttributeList +InitializeSListHead +InitializeSRWLock +InitializeSynchronizationBarrier +InstallELAMCertificateInfo +InterlockedFlushSList +InterlockedPopEntrySList +InterlockedPushEntrySList +InterlockedPushListSList +InterlockedPushListSListEx +InvalidateConsoleDIBits +IsBadCodePtr +IsBadHugeReadPtr +IsBadHugeWritePtr +IsBadReadPtr +IsBadStringPtrA +IsBadStringPtrW +IsBadWritePtr +IsCalendarLeapDay +IsCalendarLeapMonth +IsCalendarLeapYear +IsDBCSLeadByte +IsDBCSLeadByteEx +IsDebuggerPresent +IsNLSDefinedString +IsNativeVhdBoot +IsNormalizedString +IsProcessCritical +IsProcessInJob +IsProcessorFeaturePresent +IsSystemResumeAutomatic +IsThreadAFiber +IsThreadpoolTimerSet +IsTimeZoneRedirectionEnabled +IsValidCalDateTime +IsValidCodePage +IsValidLanguageGroup +IsValidLocale +IsValidUILanguage +IsValidLocaleName +IsValidNLSVersion +IsWow64Process +K32EmptyWorkingSet +K32EnumDeviceDrivers +K32EnumPageFilesA +K32EnumPageFilesW +K32EnumProcessModules +K32EnumProcessModulesEx +K32EnumProcesses +K32GetDeviceDriverBaseNameA +K32GetDeviceDriverBaseNameW +K32GetDeviceDriverFileNameA +K32GetDeviceDriverFileNameW +K32GetMappedFileNameA +K32GetMappedFileNameW +K32GetModuleBaseNameA +K32GetModuleBaseNameW +K32GetModuleFileNameExA +K32GetModuleFileNameExW +K32GetModuleInformation +K32GetPerformanceInfo +K32GetProcessImageFileNameA +K32GetProcessImageFileNameW +K32GetProcessMemoryInfo +K32GetWsChanges +K32GetWsChangesEx +K32InitializeProcessForWsWatch +K32QueryWorkingSet +K32QueryWorkingSetEx +LCIDToLocaleName +LCMapStringA +LCMapStringEx +LCMapStringW +LZClose +LZCloseFile +LZCopy +LZCreateFileW +LZDone +LZInit +LZOpenFileA +LZOpenFileW +LZRead +LZSeek +LZStart +LeaveCriticalSection +LeaveCriticalSectionWhenCallbackReturns +LoadAppInitDlls +LoadLibraryA +LoadLibraryExA +LoadLibraryExW +LoadLibraryW +LoadModule +LoadPackagedLibrary +LoadResource +LoadStringBaseExW +LoadStringBaseW +LocalAlloc +LocalCompact +LocalFileTimeToFileTime +LocalFlags +LocalFree +LocalHandle +LocalLock +LocalReAlloc +LocalShrink +LocalSize +LocalUnlock +LocaleNameToLCID +LocateExtendedFeature +LocateLegacyContext +LockFile +LockFileEx +LockResource +MapUserPhysicalPages +MapUserPhysicalPagesScatter +MapViewOfFile +MapViewOfFileEx +MapViewOfFileExNuma +MapViewOfFileFromApp +Module32First +Module32FirstW +Module32Next +Module32NextW +MoveFileA +MoveFileExA +MoveFileExW +MoveFileTransactedA +MoveFileTransactedW +MoveFileW +MoveFileWithProgressA +MoveFileWithProgressW +MulDiv +MultiByteToWideChar +NeedCurrentDirectoryForExePathA +NeedCurrentDirectoryForExePathW +NlsConvertIntegerToString +NlsCheckPolicy +NlsEventDataDescCreate +NlsGetCacheUpdateCount +NlsUpdateLocale +NlsUpdateSystemLocale +NlsResetProcessLocale +NlsWriteEtwEvent +NormalizeString +NotifyMountMgr +NotifyUILanguageChange +NtVdm64CreateProcessInternalW +OOBEComplete +OfferVirtualMemory +OpenConsoleW +OpenConsoleWStub +OpenDataFile +OpenEventA +OpenEventW +OpenFile +OpenFileById +OpenFileMappingA +OpenFileMappingW +OpenJobObjectA +OpenJobObjectW +OpenMutexA +OpenMutexW +OpenPackageInfoByFullName +OpenPrivateNamespaceA +OpenPrivateNamespaceW +OpenProcess +; MSDN says OpenProcessToken is from Advapi32.dll, not Kernel32.dll +; OpenProcessToken +OpenProfileUserMapping +OpenSemaphoreA +OpenSemaphoreW +OpenState +OpenStateExplicit +OpenThread +;OpenThreadToken +OpenWaitableTimerA +OpenWaitableTimerW +OutputDebugStringA +OutputDebugStringW +PackageFamilyNameFromFullName +PackageFamilyNameFromId +PackageFullNameFromId +PackageIdFromFullName +PackageNameAndPublisherIdFromFamilyName +ParseApplicationUserModelId +PeekConsoleInputA +PeekConsoleInputW +PeekNamedPipe +PostQueuedCompletionStatus +PowerClearRequest +PowerCreateRequest +PowerSetRequest +PrefetchVirtualMemory +PrepareTape +PrivCopyFileExW +PrivMoveFileIdentityW +Process32First +Process32FirstW +Process32Next +Process32NextW +ProcessIdToSessionId +PssCaptureSnapshot +PssDuplicateSnapshot +PssFreeSnapshot +PssQuerySnapshot +PssWalkMarkerCreate +PssWalkMarkerFree +PssWalkMarkerGetPosition +PssWalkMarkerRewind +PssWalkMarkerSeek +PssWalkMarkerSeekToBeginning +PssWalkMarkerSetPosition +PssWalkMarkerTell +PssWalkSnapshot +PulseEvent +PurgeComm +QueryActCtxSettingsW +QueryActCtxSettingsWWorker +QueryActCtxW +QueryActCtxWWorker +QueryDepthSList +QueryDosDeviceA +QueryDosDeviceW +QueryFullProcessImageNameA +QueryFullProcessImageNameW +QueryIdleProcessorCycleTime +QueryIdleProcessorCycleTimeEx +QueryInformationJobObject +QueryMemoryResourceNotification +QueryPerformanceCounter +QueryPerformanceFrequency +QueryProcessAffinityUpdateMode +QueryProcessCycleTime +QueryThreadCycleTime +QueryThreadProfiling +QueryThreadpoolStackInformation +F_X64(QueryUmsThreadInformation) +QueryUnbiasedInterruptTime +QueueUserAPC +QueueUserWorkItem +QuirkGetData2Worker +QuirkGetDataWorker +QuirkIsEnabled2Worker +QuirkIsEnabled3Worker +QuirkIsEnabledForPackage2Worker +QuirkIsEnabledForPackageWorker +QuirkIsEnabledForProcessWorker +QuirkIsEnabledWorker +RaiseException +RaiseFailFastException +RaiseInvalid16BitExeError +ReOpenFile +ReclaimVirtualMemory +ReadConsoleA +ReadConsoleInputA +ReadConsoleInputExA +ReadConsoleInputExW +ReadConsoleInputW +ReadConsoleOutputA +ReadConsoleOutputAttribute +ReadConsoleOutputCharacterA +ReadConsoleOutputCharacterW +ReadConsoleOutputW +ReadConsoleW +ReadDirectoryChangesW +ReadFile +ReadFileEx +ReadFileScatter +ReadProcessMemory +ReadThreadProfilingData +; +; MSDN says these functions are exported +; from advapi32.dll. Commented out for +; compatibility with older versions of +; Windows. +; +; RegKrnGetGlobalState and RegKrnInitialize +; are known exceptions. +; +;RegCloseKey +;RegCopyTreeW +;RegCreateKeyExA +;RegCreateKeyExW +;RegDeleteKeyExA +;RegDeleteKeyExW +;RegDeleteTreeA +;RegDeleteTreeW +;RegDeleteValueA +;RegDeleteValueW +;RegDisablePredefinedCacheEx +;RegEnumKeyExA +;RegEnumKeyExW +;RegEnumValueA +;RegEnumValueW +;RegFlushKey +;RegGetKeySecurity +;RegGetValueA +;RegGetValueW +RegKrnGetGlobalState +RegKrnInitialize +;RegLoadKeyA +;RegLoadKeyW +;RegLoadMUIStringA +;RegLoadMUIStringW +;RegNotifyChangeKeyValue +;RegOpenCurrentUser +;RegOpenKeyExA +;RegOpenKeyExW +;RegOpenUserClassesRoot +;RegQueryInfoKeyA +;RegQueryInfoKeyW +;RegQueryValueExA +;RegQueryValueExW +;RegRestoreKeyA +;RegRestoreKeyW +;RegSaveKeyExA +;RegSaveKeyExW +;RegSetKeySecurity +;RegSetValueExA +;RegSetValueExW +;RegUnLoadKeyA +;RegUnLoadKeyW +RegisterApplicationRecoveryCallback +RegisterApplicationRestart +RegisterBadMemoryNotification +RegisterConsoleIME +RegisterConsoleOS2 +RegisterConsoleVDM +RegisterWaitForInputIdle +RegisterWaitForSingleObject +RegisterWaitForSingleObjectEx +RegisterWaitUntilOOBECompleted +RegisterWowBaseHandlers +RegisterWowExec +ReleaseActCtx +ReleaseActCtxWorker +ReleaseMutex +ReleaseMutexWhenCallbackReturns +ReleaseSRWLockExclusive +ReleaseSRWLockShared +ReleaseSemaphore +ReleaseSemaphoreWhenCallbackReturns +RemoveDirectoryA +RemoveDirectoryTransactedA +RemoveDirectoryTransactedW +RemoveDirectoryW +RemoveDllDirectory +RemoveLocalAlternateComputerNameA +RemoveLocalAlternateComputerNameW +RemoveSecureMemoryCacheCallback +RemoveVectoredContinueHandler +RemoveVectoredExceptionHandler +ReplaceFile +ReplaceFileA +ReplaceFileW +ReplacePartitionUnit +RequestDeviceWakeup +RequestWakeupLatency +ResetEvent +ResetWriteWatch +ResolveDelayLoadedAPI +ResolveDelayLoadsFromDll +ResolveLocaleName +RestoreLastError +ResumeThread +RtlAddFunctionTable +RtlCaptureContext +RtlCaptureStackBackTrace +RtlCompareMemory +RtlCopyMemory +RtlDeleteFunctionTable +RtlFillMemory +RtlInstallFunctionTableCallback +RtlLookupFunctionEntry +RtlMoveMemory +RtlPcToFileHeader +RtlRaiseException +RtlRestoreContext +RtlUnwind +RtlUnwindEx +RtlVirtualUnwind +RtlZeroMemory +ScrollConsoleScreenBufferA +ScrollConsoleScreenBufferW +SearchPathA +SearchPathW +SetCachedSigningLevel +SetCPGlobal +SetCalendarInfoA +SetCalendarInfoW +SetComPlusPackageInstallStatus +SetCommBreak +SetCommConfig +SetCommMask +SetCommState +SetCommTimeouts +SetComputerNameA +SetComputerNameEx2W +SetComputerNameExA +SetComputerNameExW +SetComputerNameW +SetConsoleActiveScreenBuffer +SetConsoleCP +SetConsoleCommandHistoryMode +SetConsoleCtrlHandler +SetConsoleCursor +SetConsoleCursorInfo +SetConsoleCursorMode +SetConsoleCursorPosition +SetConsoleDisplayMode +SetConsoleFont +SetConsoleHardwareState +SetConsoleHistoryInfo +SetConsoleIcon +SetConsoleInputExeNameA +SetConsoleInputExeNameW +SetConsoleKeyShortcuts +SetConsoleLocalEUDC +SetConsoleMaximumWindowSize +SetConsoleMenuClose +SetConsoleMode +SetConsoleNlsMode +SetConsoleNumberOfCommandsA +SetConsoleNumberOfCommandsW +SetConsoleOS2OemFormat +SetConsoleOutputCP +SetConsolePalette +SetConsoleScreenBufferInfoEx +SetConsoleScreenBufferSize +SetConsoleTextAttribute +SetConsoleTitleA +SetConsoleTitleW +SetConsoleWindowInfo +SetCriticalSectionSpinCount +SetCurrentConsoleFontEx +SetCurrentDirectoryA +SetCurrentDirectoryW +SetDefaultCommConfigA +SetDefaultCommConfigW +SetDefaultDllDirectories +SetDllDirectoryA +SetDllDirectoryW +SetDynamicTimeZoneInformation +SetEndOfFile +SetEnvironmentStringsA +SetEnvironmentStringsW +SetEnvironmentVariableA +SetEnvironmentVariableW +SetErrorMode +SetEvent +SetEventWhenCallbackReturns +SetExtendedFeaturesMask +SetFileApisToANSI +SetFileApisToOEM +SetFileAttributesA +SetFileAttributesTransactedA +SetFileAttributesTransactedW +SetFileAttributesW +SetFileBandwidthReservation +SetFileCompletionNotificationModes +SetFileInformationByHandle +SetFileIoOverlappedRange +SetFilePointer +SetFilePointerEx +SetFileShortNameA +SetFileShortNameW +SetFileTime +SetFileValidData +SetFirmwareEnvironmentVariableA +SetFirmwareEnvironmentVariableExA +SetFirmwareEnvironmentVariableExW +SetFirmwareEnvironmentVariableW +SetHandleCount +SetHandleInformation +SetInformationJobObject +SetLastConsoleEventActive +SetLastError +SetLocalPrimaryComputerNameA +SetLocalPrimaryComputerNameW +SetLocalTime +SetLocaleInfoA +SetLocaleInfoW +SetMailslotInfo +SetMessageWaitingIndicator +SetNamedPipeAttribute +SetNamedPipeHandleState +SetPriorityClass +SetProcessAffinityMask +SetProcessAffinityUpdateMode +SetProcessDEPPolicy +SetProcessInformation +SetProcessMitigationPolicy +SetProcessPreferredUILanguages +SetProcessPriorityBoost +SetProcessShutdownParameters +SetProcessWorkingSetSize +SetProcessWorkingSetSizeEx +SetSearchPathMode +SetStdHandle +SetStdHandleEx +SetSystemFileCacheSize +SetSystemPowerState +SetSystemTime +SetSystemTimeAdjustment +SetTapeParameters +SetTapePosition +SetTermsrvAppInstallMode +SetThreadAffinityMask +SetThreadContext +SetThreadErrorMode +SetThreadExecutionState +SetThreadGroupAffinity +SetThreadIdealProcessor +SetThreadIdealProcessorEx +SetThreadInformation +SetThreadLocale +SetThreadPreferredUILanguages +SetThreadPriority +SetThreadPriorityBoost +SetThreadStackGuarantee +SetThreadToken +SetThreadUILanguage +SetThreadpoolStackInformation +SetThreadpoolThreadMaximum +SetThreadpoolThreadMinimum +SetThreadpoolTimer +SetThreadpoolTimerEx +SetThreadpoolWait +SetThreadpoolWaitEx +SetTimeZoneInformation +SetTimerQueueTimer +F_X64(SetUmsThreadInformation) +SetUnhandledExceptionFilter +SetUserGeoID +SetVDMCurrentDirectories +SetVolumeLabelA +SetVolumeLabelW +SetVolumeMountPointA +SetVolumeMountPointW +SetVolumeMountPointWStub +SetWaitableTimer +SetWaitableTimerEx +SetupComm +ShowConsoleCursor +SignalObjectAndWait +SizeofResource +Sleep +SleepConditionVariableCS +SleepConditionVariableSRW +SleepEx +SortCloseHandle +SortGetHandle +StartThreadpoolIo +SubmitThreadpoolWork +SuspendThread +SwitchToFiber +SwitchToThread +SystemTimeToFileTime +SystemTimeToTzSpecificLocalTime +SystemTimeToTzSpecificLocalTimeEx +TerminateJobObject +TerminateProcess +TerminateThread +TermsrvAppInstallMode +TermsrvConvertSysRootToUserDir +TermsrvCreateRegEntry +TermsrvDeleteKey +TermsrvDeleteValue +TermsrvGetPreSetValue +TermsrvGetWindowsDirectoryA +TermsrvGetWindowsDirectoryW +TermsrvOpenRegEntry +TermsrvOpenUserClasses +TermsrvRestoreKey +TermsrvSetKeySecurity +TermsrvSetValueKey +TermsrvSyncUserIniFileExt +Thread32First +Thread32Next +TlsAlloc +TlsFree +TlsGetValue +TlsSetValue +Toolhelp32ReadProcessMemory +TransactNamedPipe +TransmitCommChar +TryAcquireSRWLockExclusive +TryAcquireSRWLockShared +TryEnterCriticalSection +TrySubmitThreadpoolCallback +TzSpecificLocalTimeToSystemTime +TzSpecificLocalTimeToSystemTimeEx +UTRegister +UTUnRegister +F_X64(UmsThreadYield) +UnhandledExceptionFilter +UnlockFile +UnlockFileEx +UnmapViewOfFile +UnmapViewOfFileEx +UnregisterApplicationRecoveryCallback +UnregisterApplicationRestart +UnregisterBadMemoryNotification +UnregisterConsoleIME +UnregisterWait +UnregisterWaitEx +UnregisterWaitUntilOOBECompleted +UpdateCalendarDayOfWeek +UpdateProcThreadAttribute +UpdateResourceA +UpdateResourceW +VDMConsoleOperation +VDMOperationStarted +ValidateLCType +ValidateLocale +VerLanguageNameA +VerLanguageNameW +VerSetConditionMask +VerifyConsoleIoHandle +VerifyScripts +VerifyVersionInfoA +VerifyVersionInfoW +VirtualAlloc +VirtualAllocEx +VirtualAllocExNuma +VirtualFree +VirtualFreeEx +VirtualLock +VirtualProtect +VirtualProtectEx +VirtualQuery +VirtualQueryEx +VirtualUnlock +WTSGetActiveConsoleSessionId +WaitCommEvent +WaitForDebugEvent +WaitForMultipleObjects +WaitForMultipleObjectsEx +WaitForSingleObject +WaitForSingleObjectEx +WaitForThreadpoolIoCallbacks +WaitForThreadpoolTimerCallbacks +WaitForThreadpoolWaitCallbacks +WaitForThreadpoolWorkCallbacks +WaitNamedPipeA +WaitNamedPipeW +WaitOnAddress +WakeAllConditionVariable +WakeByAddressSingle +WakeByAddressAll +WakeConditionVariable +WerGetFlags +WerRegisterFile +WerRegisterFileWorker +WerRegisterMemoryBlock +WerRegisterMemoryBlockWorker +WerRegisterRuntimeExceptionModule +WerRegisterRuntimeExceptionModuleWorker +WerSetFlags +WerUnregisterFile +WerUnregisterFileWorker +WerUnregisterMemoryBlock +WerUnregisterMemoryBlockWorker +WerUnregisterRuntimeExceptionModule +WerUnregisterRuntimeExceptionModuleWorker +WerpCleanupMessageMapping +WerpGetDebugger +WerpInitiateRemoteRecovery +WerpLaunchAeDebug +WerpNotifyLoadStringResource +WerpNotifyLoadStringResourceEx +WerpNotifyLoadStringResourceWorker +WerpNotifyUseStringResource +WerpNotifyUseStringResourceWorker +WerpStringLookup +WideCharToMultiByte +WinExec +Wow64DisableWow64FsRedirection +Wow64EnableWow64FsRedirection +Wow64GetThreadContext +Wow64GetThreadSelectorEntry +Wow64RevertWow64FsRedirection +Wow64SetThreadContext +Wow64SuspendThread +WriteConsoleA +WriteConsoleInputA +WriteConsoleInputVDMA +WriteConsoleInputVDMW +WriteConsoleInputW +WriteConsoleOutputA +WriteConsoleOutputAttribute +WriteConsoleOutputCharacterA +WriteConsoleOutputCharacterW +WriteConsoleOutputW +WriteConsoleW +WriteFile +WriteFileEx +WriteFileGather +WritePrivateProfileSectionA +WritePrivateProfileSectionW +WritePrivateProfileStringA +WritePrivateProfileStringW +WritePrivateProfileStructA +WritePrivateProfileStructW +WriteProcessMemory +WriteProfileSectionA +WriteProfileSectionW +WriteProfileStringA +WriteProfileStringW +WriteTapemark +ZombifyActCtx +ZombifyActCtxWorker +__C_specific_handler +F_ARM32(__chkstk) +F_X64(__misaligned_access) +_hread +_hwrite +_lclose +_lcreat +_llseek +_local_unwind +_lopen +_lread +_lwrite +lstrcat +lstrcatA +lstrcatW +lstrcmp +lstrcmpA +lstrcmpW +lstrcmpi +lstrcmpiA +lstrcmpiW +lstrcpy +lstrcpyA +lstrcpyW +lstrcpyn +lstrcpynA +lstrcpynW +lstrlen +lstrlenA +lstrlenW +uaw_lstrcmpW +uaw_lstrcmpiW +uaw_lstrlenW +uaw_wcschr +uaw_wcscpy +uaw_wcsicmp +uaw_wcslen +uaw_wcsrchr diff --git a/libc/mingw/misc/__p___argv.c b/libc/mingw/misc/__p___argv.c new file mode 100644 index 0000000000..8e1f8ed9ac --- /dev/null +++ b/libc/mingw/misc/__p___argv.c @@ -0,0 +1,15 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include + +char ***__cdecl __p___argv(void) +{ + return __MINGW_IMP_SYMBOL(__argv); +} + +typedef char ***__cdecl (*_f__p___argv)(void); +_f__p___argv __MINGW_IMP_SYMBOL(__p___argv) = __p___argv; diff --git a/libc/mingw/misc/__p__acmdln.c b/libc/mingw/misc/__p__acmdln.c new file mode 100644 index 0000000000..14e3868e5a --- /dev/null +++ b/libc/mingw/misc/__p__acmdln.c @@ -0,0 +1,18 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <_mingw.h> + +extern char ** __MINGW_IMP_SYMBOL(_acmdln); + +char **__cdecl __p__acmdln(void); +char **__cdecl __p__acmdln(void) +{ + return __MINGW_IMP_SYMBOL(_acmdln); +} + +typedef char **__cdecl (*_f__p__acmdln)(void); +_f__p__acmdln __MINGW_IMP_SYMBOL(__p__acmdln) = __p__acmdln; diff --git a/libc/mingw/misc/__p__fmode.c b/libc/mingw/misc/__p__fmode.c new file mode 100644 index 0000000000..f788a6fcc9 --- /dev/null +++ b/libc/mingw/misc/__p__fmode.c @@ -0,0 +1,17 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include <_mingw.h> + +extern int * __MINGW_IMP_SYMBOL(_fmode); + +int *__cdecl __p__fmode(void); +int *__cdecl __p__fmode(void) +{ + return __MINGW_IMP_SYMBOL(_fmode); +} + +typeof(__p__fmode) *__MINGW_IMP_SYMBOL(__p__fmode) = __p__fmode; diff --git a/libc/mingw/misc/__p__wcmdln.c b/libc/mingw/misc/__p__wcmdln.c new file mode 100644 index 0000000000..f34390468d --- /dev/null +++ b/libc/mingw/misc/__p__wcmdln.c @@ -0,0 +1,18 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include + +extern wchar_t ** __MINGW_IMP_SYMBOL(_wcmdln); + +wchar_t **__cdecl __p__wcmdln(void); +wchar_t **__cdecl __p__wcmdln(void) +{ + return __MINGW_IMP_SYMBOL(_wcmdln); +} + +typedef wchar_t **__cdecl (*_f__p__wcmdln)(void); +_f__p__wcmdln __MINGW_IMP_SYMBOL(__p__wcmdln) = __p__wcmdln; diff --git a/libc/mingw/misc/_configthreadlocale.c b/libc/mingw/misc/_configthreadlocale.c new file mode 100644 index 0000000000..cbc60139bf --- /dev/null +++ b/libc/mingw/misc/_configthreadlocale.c @@ -0,0 +1,16 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include + +int __cdecl _configthreadlocale(int flag) +{ + /* _ENABLE_PER_THREAD_LOCALE can't work on msvcrt.dll. */ + return flag == _ENABLE_PER_THREAD_LOCALE ? -1 : _DISABLE_PER_THREAD_LOCALE; +} + +void *__MINGW_IMP_SYMBOL(_configthreadlocale) = _configthreadlocale; + diff --git a/libc/mingw/misc/_get_current_locale.c b/libc/mingw/misc/_get_current_locale.c new file mode 100644 index 0000000000..f5ccc4afc1 --- /dev/null +++ b/libc/mingw/misc/_get_current_locale.c @@ -0,0 +1,26 @@ +#include +#include +#include + +static _locale_t __cdecl init_func(void); +_locale_t (__cdecl *__MINGW_IMP_SYMBOL(_get_current_locale))(void) = init_func; + +static _locale_t __cdecl null_func(void) +{ + return NULL; +} + +static _locale_t __cdecl init_func(void) +{ + HMODULE msvcrt = __mingw_get_msvcrt_handle(); + _locale_t (__cdecl *func)(void) = NULL; + + if (msvcrt) { + func = (void*)GetProcAddress(msvcrt, "_get_current_locale"); + } + + if (!func) + func = null_func; + + return (__MINGW_IMP_SYMBOL(_get_current_locale) = func)(); +} diff --git a/libc/mingw/misc/invalid_parameter_handler.c b/libc/mingw/misc/invalid_parameter_handler.c new file mode 100644 index 0000000000..972b8598cb --- /dev/null +++ b/libc/mingw/misc/invalid_parameter_handler.c @@ -0,0 +1,23 @@ +#define _CRTIMP +#include + +typedef void (__cdecl *_invalid_parameter_handler)(const wchar_t *,const wchar_t *,const wchar_t *,unsigned int,uintptr_t); +static _invalid_parameter_handler handler; + +static _invalid_parameter_handler __cdecl mingw_set_invalid_parameter_handler(_invalid_parameter_handler new_handler) +{ + return InterlockedExchangePointer((void**)&handler, new_handler); +} + +_invalid_parameter_handler (__cdecl *__MINGW_IMP_SYMBOL(_set_invalid_parameter_handler))(_invalid_parameter_handler) = + mingw_set_invalid_parameter_handler; + +static _invalid_parameter_handler __cdecl mingw_get_invalid_parameter_handler(void) +{ + return handler; +} + +_invalid_parameter_handler (__cdecl *__MINGW_IMP_SYMBOL(_get_invalid_parameter_handler))(void) = mingw_get_invalid_parameter_handler; + +_invalid_parameter_handler __cdecl _get_invalid_parameter_handler(void) __attribute__ ((alias ("mingw_get_invalid_parameter_handler"))); +_invalid_parameter_handler __cdecl _set_invalid_parameter_handler(_invalid_parameter_handler new_handler) __attribute__ ((alias ("mingw_set_invalid_parameter_handler"))); diff --git a/libc/mingw/misc/lc_locale_func.c b/libc/mingw/misc/lc_locale_func.c new file mode 100644 index 0000000000..e6847ae8b6 --- /dev/null +++ b/libc/mingw/misc/lc_locale_func.c @@ -0,0 +1,50 @@ +#define __lc_codepage __dummy_lc_codepage +#define ___lc_codepage_func __dummy____lc_codepage_func +#include +#include +#include + +#undef __lc_codepage +#undef ___lc_codepage_func +#include "mb_wc_common.h" + +static unsigned int *msvcrt__lc_codepage; +static unsigned int __cdecl msvcrt___lc_codepage_func(void) +{ + return *msvcrt__lc_codepage; +} + +static unsigned int __cdecl setlocale_codepage_hack(void) +{ + /* locale :: "lang[_country[.code_page]]" | ".code_page" */ + const char *cp_str = strchr (setlocale(LC_CTYPE, NULL), '.'); + return cp_str ? atoi(cp_str + 1) : 0; +} + +static unsigned int __cdecl init_codepage_func(void); +unsigned int (__cdecl *__MINGW_IMP_SYMBOL(___lc_codepage_func))(void) = init_codepage_func; + +unsigned int __cdecl ___lc_codepage_func (void) +{ + return __MINGW_IMP_SYMBOL(___lc_codepage_func) (); +} + +static unsigned int __cdecl init_codepage_func(void) +{ + HMODULE msvcrt = __mingw_get_msvcrt_handle(); + unsigned int (__cdecl *func)(void) = NULL; + + if(msvcrt) { + func = (void*)GetProcAddress(msvcrt, "___lc_codepage_func"); + if(!func) { + msvcrt__lc_codepage = (unsigned int*)GetProcAddress(msvcrt, "__lc_codepage"); + if(msvcrt__lc_codepage) + func = msvcrt___lc_codepage_func; + } + } + + if(!func) + func = setlocale_codepage_hack; + + return (__MINGW_IMP_SYMBOL(___lc_codepage_func) = func)(); +} diff --git a/libc/mingw/misc/onexit_table.c b/libc/mingw/misc/onexit_table.c new file mode 100644 index 0000000000..69f2ea7166 --- /dev/null +++ b/libc/mingw/misc/onexit_table.c @@ -0,0 +1,77 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include +#include + +#define _EXIT_LOCK1 8 + +void __cdecl _lock (int _File); +void __cdecl _unlock (int _File); + +int __cdecl _initialize_onexit_table(_onexit_table_t *table) +{ + if (!table) return -1; + table->_first = table->_last = table->_end = NULL; + return 0; +} + +int __cdecl _register_onexit_function(_onexit_table_t *table, _onexit_t func) +{ + if (!table) return -1; + + _lock(_EXIT_LOCK1); + + if (!table->_first) { + table->_first = calloc(32, sizeof(void*)); + if (!table->_first) { + _unlock(_EXIT_LOCK1); + return -1; + } + table->_last = table->_first; + table->_end = table->_first + 32; + } + + if (table->_last == table->_end) { + size_t len = table->_end - table->_first; + _PVFV *new_buf = realloc(table->_first, len * sizeof(void*) * 2); + if (!new_buf) { + _unlock(_EXIT_LOCK1); + return -1; + } + table->_first = new_buf; + table->_last = new_buf + len; + table->_end = new_buf + len * 2; + } + + *table->_last++ = (_PVFV)func; + _unlock(_EXIT_LOCK1); + return 0; +} + +int __cdecl _execute_onexit_table(_onexit_table_t *table) +{ + _PVFV *first, *last; + + _lock(_EXIT_LOCK1); + first = table->_first; + last = table->_last; + _initialize_onexit_table(table); + _unlock(_EXIT_LOCK1); + + if (!first) return 0; + + while (--last >= first) + if (*last) + (**last)(); + + free(first); + return 0; +} + +typeof(_initialize_onexit_table) *__MINGW_IMP_SYMBOL(_initialize_onexit_table) = _initialize_onexit_table; +typeof(_register_onexit_function) *__MINGW_IMP_SYMBOL(_register_onexit_function) = _register_onexit_function; +typeof(_execute_onexit_table) *__MINGW_IMP_SYMBOL(_execute_onexit_table) = _execute_onexit_table; diff --git a/libc/mingw/misc/output_format.c b/libc/mingw/misc/output_format.c new file mode 100644 index 0000000000..da037556c9 --- /dev/null +++ b/libc/mingw/misc/output_format.c @@ -0,0 +1,62 @@ +#define _get_output_format __dummy__get_output_format +#define _set_output_format __dummy__set_output_format +#include +#include + +#undef _get_output_format +#undef _set_output_format + +static unsigned int last_value = 0; +typedef unsigned int (*f_get_output_format)(void); +typedef unsigned int (*f_set_output_format)(unsigned int); + +static unsigned int init_set_output_format(unsigned int); +f_set_output_format __MINGW_IMP_SYMBOL(_set_output_format) = init_set_output_format; + +unsigned int _set_output_format(unsigned int format); +unsigned int _set_output_format(unsigned int format) +{ + return __MINGW_IMP_SYMBOL(_set_output_format)(format); +} + +static unsigned int fake_set_output_format(unsigned int value) +{ + return InterlockedExchange((LONG*)&last_value, value); +} + +static unsigned int init_set_output_format(unsigned int format) +{ + f_set_output_format sof; + + sof = (f_set_output_format) GetProcAddress (__mingw_get_msvcrt_handle(), "_set_output_format"); + if(!sof) + sof = fake_set_output_format; + + return (__MINGW_IMP_SYMBOL(_set_output_format) = sof)(format); +} + + +static unsigned int init_get_output_format(void); +f_get_output_format __MINGW_IMP_SYMBOL(_get_output_format) = init_get_output_format; + +unsigned int _get_output_format(void); +unsigned int _get_output_format(void) +{ + return __MINGW_IMP_SYMBOL(_get_output_format)(); +} + +static unsigned int fake_get_output_format(void) +{ + return last_value; +} + +static unsigned int init_get_output_format(void) +{ + f_get_output_format gof; + + gof = (f_get_output_format) GetProcAddress (__mingw_get_msvcrt_handle(), "_get_output_format"); + if(!gof) + gof = fake_get_output_format; + + return (__MINGW_IMP_SYMBOL(_get_output_format) = gof)(); +} diff --git a/libc/mingw/misc/purecall.c b/libc/mingw/misc/purecall.c new file mode 100644 index 0000000000..8c29e67609 --- /dev/null +++ b/libc/mingw/misc/purecall.c @@ -0,0 +1,18 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#define _CRTIMP +#include +#include + +_purecall_handler __cdecl _set_purecall_handler(_purecall_handler handler) +{ + static _purecall_handler prev_handler; + return InterlockedExchangePointer((void**)&prev_handler, handler); +} + +void *__MINGW_IMP_SYMBOL(_set_purecall_handler) = _set_purecall_handler; + diff --git a/libc/mingw/misc/register_tls_atexit.c b/libc/mingw/misc/register_tls_atexit.c new file mode 100644 index 0000000000..09d9270e4d --- /dev/null +++ b/libc/mingw/misc/register_tls_atexit.c @@ -0,0 +1,29 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include +#include +#include +#include + +static _tls_callback_type callback; + +static void run_callback(void) +{ + if (callback) + callback(NULL, DLL_PROCESS_DETACH, 0); + callback = NULL; +} + +void __cdecl _register_thread_local_exe_atexit_callback(_tls_callback_type cb) +{ + callback = cb; + /* This should guarantee that the callback is called. It won't be run in the + * exact right spot as intended to, but it will be run. */ + atexit(run_callback); +} + +typeof(_register_thread_local_exe_atexit_callback) *__MINGW_IMP_SYMBOL(_register_thread_local_exe_atexit_callback) = _register_thread_local_exe_atexit_callback; diff --git a/libc/mingw/secapi/_access_s.c b/libc/mingw/secapi/_access_s.c new file mode 100644 index 0000000000..9be582e878 --- /dev/null +++ b/libc/mingw/secapi/_access_s.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_access_s (const char *, int); +static errno_t __cdecl _stub (const char *, int); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_access_s))(const char *, int) = + _stub; + +static errno_t __cdecl +_stub (const char *s, int m) +{ + errno_t __cdecl (*f)(const char *, int) = __MINGW_IMP_SYMBOL(_access_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(const char *, int)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_access_s"); + if (!f) + f = _int_access_s; + __MINGW_IMP_SYMBOL(_access_s) = f; + } + return (*f)(s, m); +} + +errno_t __cdecl +_access_s (const char *s, int m) +{ + return _stub (s, m); +} + +static errno_t __cdecl +_int_access_s (const char *s, int m) +{ + if (!s || (m & ~6) != 0) + { + _access (NULL, m); + return EINVAL; + } + if (!_access (s, m)) + return 0; + return errno; +} diff --git a/libc/mingw/secapi/_cgets_s.c b/libc/mingw/secapi/_cgets_s.c new file mode 100644 index 0000000000..e70efe7253 --- /dev/null +++ b/libc/mingw/secapi/_cgets_s.c @@ -0,0 +1,56 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_cgets_s (char *, size_t, size_t *); +static errno_t __cdecl _stub (char *, size_t, size_t *); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_cgets_s))(char *, size_t, size_t *) = + _stub; + +static errno_t __cdecl +_stub (char *s, size_t l, size_t *r_len) +{ + errno_t __cdecl (*f)(char *, size_t, size_t *) = __MINGW_IMP_SYMBOL(_cgets_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(char *, size_t, size_t *)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_cgets_s"); + if (!f) + f = _int_cgets_s; + __MINGW_IMP_SYMBOL(_cgets_s) = f; + } + return (*f)(s, l, r_len); +} + +errno_t __cdecl +_cgets_s (char *s, size_t l, size_t *r_len) +{ + return _stub (s, l, r_len); +} + +static errno_t __cdecl +_int_cgets_s (char *s, size_t l, size_t *r_len) +{ + char *h, *p; + + if (s && l) + s[0] = 0; + if (!s || !l || !r_len) + { + _cgets (NULL); + return EINVAL; + } + p = (char *) alloca (l + 2); + p[0] = l; + h = _cgets (s); + if (!h) + return EINVAL; + *r_len = (size_t) p[1]; + memcpy (s, &p[2], *r_len); + return 0; +} diff --git a/libc/mingw/secapi/_cgetws_s.c b/libc/mingw/secapi/_cgetws_s.c new file mode 100644 index 0000000000..dff4187096 --- /dev/null +++ b/libc/mingw/secapi/_cgetws_s.c @@ -0,0 +1,56 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_cgetws_s (wchar_t *, size_t, size_t *); +static errno_t __cdecl _stub (wchar_t *, size_t, size_t *); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_cgetws_s))(wchar_t *, size_t, size_t *) = + _stub; + +static errno_t __cdecl +_stub (wchar_t *s, size_t l, size_t *r_len) +{ + errno_t __cdecl (*f)(wchar_t *, size_t, size_t *) = __MINGW_IMP_SYMBOL(_cgetws_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(wchar_t *, size_t, size_t *)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_cgetws_s"); + if (!f) + f = _int_cgetws_s; + __MINGW_IMP_SYMBOL(_cgetws_s) = f; + } + return (*f)(s, l, r_len); +} + +errno_t __cdecl +_cgetws_s (wchar_t *s, size_t l, size_t *r_len) +{ + return _stub (s, l, r_len); +} + +static errno_t __cdecl +_int_cgetws_s (wchar_t *s, size_t l, size_t *r_len) +{ + wchar_t *h, *p; + + if (s && l) + s[0] = 0; + if (!s || !l || !r_len) + { + _cgetws (NULL); + return EINVAL; + } + p = (wchar_t *) alloca ((l + 2) * sizeof (wchar_t)); + p[0] = l; + h = _cgetws (s); + if (!h) + return EINVAL; + *r_len = (size_t) p[1]; + memcpy (s, &p[2], *r_len); + return 0; +} diff --git a/libc/mingw/secapi/_chsize_s.c b/libc/mingw/secapi/_chsize_s.c new file mode 100644 index 0000000000..cd8d066ebb --- /dev/null +++ b/libc/mingw/secapi/_chsize_s.c @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_chsize_s (int, long long); +static errno_t __cdecl _stub (int, long long); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_chsize_s))(int, long long) = + _stub; + +static errno_t __cdecl +_stub (int fd, long long sz) +{ + errno_t __cdecl (*f)(int, long long) = __MINGW_IMP_SYMBOL(_chsize_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(int, long long)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_chsize_s"); + if (!f) + f = _int_chsize_s; + __MINGW_IMP_SYMBOL(_chsize_s) = f; + } + return (*f)(fd, sz); +} + +errno_t __cdecl +_chsize_s (int fd, long long sz) +{ + return _stub (fd, sz); +} + +static errno_t __cdecl +_int_chsize_s (int fd, long long sz) +{ + if (sz > 0x7fffffffll) + { + /* We can't set file bigger as 2GB, so return EACCES. */ + return (errno = EACCES); + } + if (!_chsize (fd, sz)) + return 0; + return errno; +} diff --git a/libc/mingw/secapi/_controlfp_s.c b/libc/mingw/secapi/_controlfp_s.c new file mode 100644 index 0000000000..32be17cfb8 --- /dev/null +++ b/libc/mingw/secapi/_controlfp_s.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include + +static errno_t __cdecl _stub( + unsigned int *currentControl, + unsigned int newControl, + unsigned int mask +); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_controlfp_s))(unsigned int *, unsigned int, unsigned int) = _stub; + +errno_t __cdecl _controlfp_s( + unsigned int *currentControl, + unsigned int newControl, + unsigned int mask +){ + return __MINGW_IMP_SYMBOL(_controlfp_s)(currentControl,newControl,mask); +} + +static const unsigned int allflags = _MCW_DN | _MCW_EM | _MCW_IC | _MCW_RC | _MCW_PC; +static errno_t __cdecl _int_controlfp_s( + unsigned int *currentControl, + unsigned int newControl, + unsigned int mask +){ + unsigned int cont; + if(!(newControl & mask & ~allflags)){ + if (currentControl) *currentControl = _controlfp( 0, 0 ); + return EINVAL; + } + cont = _controlfp( newControl, mask ); + if(currentControl) *currentControl = cont; + return 0; +} + +static errno_t __cdecl _stub ( + unsigned int *currentControl, + unsigned int newControl, + unsigned int mask +) +{ + errno_t __cdecl (*f)(unsigned int *, unsigned int, unsigned int) = __MINGW_IMP_SYMBOL(_controlfp_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(unsigned int *, unsigned int, unsigned int)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_controlfp_s"); + if (!f) + f = _int_controlfp_s; + __MINGW_IMP_SYMBOL(_controlfp_s) = f; + } + return (*f)(currentControl, newControl, mask); +} + diff --git a/libc/mingw/secapi/_cprintf_s.c b/libc/mingw/secapi/_cprintf_s.c new file mode 100644 index 0000000000..36ea582d41 --- /dev/null +++ b/libc/mingw/secapi/_cprintf_s.c @@ -0,0 +1,21 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include +#include + +int __cdecl (*__MINGW_IMP_SYMBOL(_cprintf_s))(const char *,...) = + _cprintf_s; + +int __cdecl +_cprintf_s (const char *s, ...) +{ + va_list argp; + int r; + + va_start (argp, s); + r = _vcprintf_s (s, argp); + va_end (argp); + return r; +} diff --git a/libc/mingw/secapi/_cprintf_s_l.c b/libc/mingw/secapi/_cprintf_s_l.c new file mode 100644 index 0000000000..316ca86ef3 --- /dev/null +++ b/libc/mingw/secapi/_cprintf_s_l.c @@ -0,0 +1,21 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include +#include + +int __cdecl (*__MINGW_IMP_SYMBOL(_cprintf_s_l))(const char *, _locale_t, ...) = + _cprintf_s_l; + +int __cdecl +_cprintf_s_l (const char *s, _locale_t loc, ...) +{ + va_list argp; + int r; + + va_start (argp, loc); + r = _vcprintf_s_l (s, loc, argp); + va_end (argp); + return r; +} diff --git a/libc/mingw/secapi/_ctime32_s.c b/libc/mingw/secapi/_ctime32_s.c new file mode 100644 index 0000000000..c59ccfc190 --- /dev/null +++ b/libc/mingw/secapi/_ctime32_s.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_ctime32_s (char *, size_t, const __time32_t *); +static errno_t __cdecl _stub (char *, size_t, const __time32_t *); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_ctime32_s))(char *, size_t, const __time32_t *) = + _stub; + +static errno_t __cdecl +_stub (char *d, size_t dn, const __time32_t *pt) +{ + errno_t __cdecl (*f)(char *, size_t, const __time32_t *) = __MINGW_IMP_SYMBOL(_ctime32_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(char *, size_t, const __time32_t *)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_ctime32_s"); + if (!f) + f = _int_ctime32_s; + __MINGW_IMP_SYMBOL(_ctime32_s) = f; + } + return (*f)(d, dn, pt); +} + +errno_t __cdecl +_ctime32_s (char *d, size_t dn, const __time32_t *pt) +{ + return _stub (d, dn, pt); +} + +static errno_t __cdecl +_int_ctime32_s (char *d, size_t dn, const __time32_t *pt) +{ + struct tm ltm; + errno_t e; + + if (!d || !dn) + { + errno = EINVAL; + return EINVAL; + } + d[0] = 0; + if (!pt) + { + errno = EINVAL; + return EINVAL; + } + + if ((e = _localtime32_s (<m, pt)) != 0) + return e; + return asctime_s (d, dn, <m); +} diff --git a/libc/mingw/secapi/_ctime64_s.c b/libc/mingw/secapi/_ctime64_s.c new file mode 100644 index 0000000000..833d14a0aa --- /dev/null +++ b/libc/mingw/secapi/_ctime64_s.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_ctime64_s (char *, size_t, const __time64_t *); +static errno_t __cdecl _stub (char *, size_t, const __time64_t *); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_ctime64_s))(char *, size_t, const __time64_t *) = + _stub; + +static errno_t __cdecl +_stub (char *d, size_t dn, const __time64_t *pt) +{ + errno_t __cdecl (*f)(char *, size_t, const __time64_t *) = __MINGW_IMP_SYMBOL(_ctime64_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(char *, size_t, const __time64_t *)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_ctime64_s"); + if (!f) + f = _int_ctime64_s; + __MINGW_IMP_SYMBOL(_ctime64_s) = f; + } + return (*f)(d, dn, pt); +} + +errno_t __cdecl +_ctime64_s (char *d, size_t dn, const __time64_t *pt) +{ + return _stub (d, dn, pt); +} + +static errno_t __cdecl +_int_ctime64_s (char *d, size_t dn, const __time64_t *pt) +{ + struct tm ltm; + errno_t e; + + if (!d || !dn) + { + errno = EINVAL; + return EINVAL; + } + d[0] = 0; + if (!pt) + { + errno = EINVAL; + return EINVAL; + } + + if ((e = _localtime64_s (<m, pt)) != 0) + return e; + return asctime_s (d, dn, <m); +} diff --git a/libc/mingw/secapi/_cwprintf_s.c b/libc/mingw/secapi/_cwprintf_s.c new file mode 100644 index 0000000000..b5ce0ab940 --- /dev/null +++ b/libc/mingw/secapi/_cwprintf_s.c @@ -0,0 +1,21 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include +#include + +int __cdecl (*__MINGW_IMP_SYMBOL(_cwprintf_s))(const wchar_t *,...) = + _cwprintf_s; + +int __cdecl +_cwprintf_s (const wchar_t *s, ...) +{ + va_list argp; + int r; + + va_start (argp, s); + r = _vcwprintf_s (s, argp); + va_end (argp); + return r; +} diff --git a/libc/mingw/secapi/_cwprintf_s_l.c b/libc/mingw/secapi/_cwprintf_s_l.c new file mode 100644 index 0000000000..cadd55d022 --- /dev/null +++ b/libc/mingw/secapi/_cwprintf_s_l.c @@ -0,0 +1,21 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include +#include + +int __cdecl (*__MINGW_IMP_SYMBOL(_cwprintf_s_l))(const wchar_t *, _locale_t, ...) = + _cwprintf_s_l; + +int __cdecl +_cwprintf_s_l (const wchar_t *s, _locale_t loc, ...) +{ + va_list argp; + int r; + + va_start (argp, loc); + r = _vcwprintf_s_l (s, loc, argp); + va_end (argp); + return r; +} diff --git a/libc/mingw/secapi/_gmtime32_s.c b/libc/mingw/secapi/_gmtime32_s.c new file mode 100644 index 0000000000..7139c24df1 --- /dev/null +++ b/libc/mingw/secapi/_gmtime32_s.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_gmtime32_s (struct tm *, const __time32_t *); +static errno_t __cdecl _stub (struct tm *, const __time32_t *); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_gmtime32_s))(struct tm *, const __time32_t *) = + _stub; + +static errno_t __cdecl +_stub (struct tm *ptm, const __time32_t *pt) +{ + errno_t __cdecl (*f)(struct tm *, const __time32_t *) = __MINGW_IMP_SYMBOL(_gmtime32_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(struct tm *, const __time32_t *)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_gmtime32_s"); + if (!f) + f = _int_gmtime32_s; + __MINGW_IMP_SYMBOL(_gmtime32_s) = f; + } + return (*f)(ptm, pt); +} + +errno_t __cdecl +_gmtime32_s (struct tm *ptm, const __time32_t *pt) +{ + return _stub (ptm, pt); +} + +static errno_t __cdecl +_int_gmtime32_s (struct tm *ptm, const __time32_t *pt) +{ + struct tm *ltm; + + if (ptm) + memset (ptm, 0xff, sizeof (*ptm)); + if (!ptm || !pt) + { + errno = EINVAL; + return EINVAL; + } + if ((ltm = _gmtime32 (pt)) == NULL) + return errno; + *ptm = *ltm; + return 0; +} diff --git a/libc/mingw/secapi/_gmtime64_s.c b/libc/mingw/secapi/_gmtime64_s.c new file mode 100644 index 0000000000..c4ca154684 --- /dev/null +++ b/libc/mingw/secapi/_gmtime64_s.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_gmtime64_s (struct tm *, const __time64_t *); +static errno_t __cdecl _stub (struct tm *, const __time64_t *); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_gmtime64_s))(struct tm *, const __time64_t *) = + _stub; + +static errno_t __cdecl +_stub (struct tm *ptm, const __time64_t *pt) +{ + errno_t __cdecl (*f)(struct tm *, const __time64_t *) = __MINGW_IMP_SYMBOL(_gmtime64_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(struct tm *, const __time64_t *)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_gmtime64_s"); + if (!f) + f = _int_gmtime64_s; + __MINGW_IMP_SYMBOL(_gmtime64_s) = f; + } + return (*f)(ptm, pt); +} + +errno_t __cdecl +_gmtime64_s (struct tm *ptm, const __time64_t *pt) +{ + return _stub (ptm, pt); +} + +static errno_t __cdecl +_int_gmtime64_s (struct tm *ptm, const __time64_t *pt) +{ + struct tm *ltm; + + if (ptm) + memset (ptm, 0xff, sizeof (*ptm)); + if (!ptm || !pt) + { + errno = EINVAL; + return EINVAL; + } + if ((ltm = _gmtime64 (pt)) == NULL) + return errno; + *ptm = *ltm; + return 0; +} diff --git a/libc/mingw/secapi/_localtime32_s.c b/libc/mingw/secapi/_localtime32_s.c new file mode 100644 index 0000000000..c8a62f6cce --- /dev/null +++ b/libc/mingw/secapi/_localtime32_s.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_localtime32_s (struct tm *, const __time32_t *); +static errno_t __cdecl _stub (struct tm *, const __time32_t *); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_localtime32_s))(struct tm *, const __time32_t *) = + _stub; + +static errno_t __cdecl +_stub (struct tm *ptm, const __time32_t *pt) +{ + errno_t __cdecl (*f)(struct tm *, const __time32_t *) = __MINGW_IMP_SYMBOL(_localtime32_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(struct tm *, const __time32_t *)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_localtime32_s"); + if (!f) + f = _int_localtime32_s; + __MINGW_IMP_SYMBOL(_localtime32_s) = f; + } + return (*f)(ptm, pt); +} + +errno_t __cdecl +_localtime32_s (struct tm *ptm, const __time32_t *pt) +{ + return _stub (ptm, pt); +} + +static errno_t __cdecl +_int_localtime32_s (struct tm *ptm, const __time32_t *pt) +{ + struct tm *ltm; + + if (ptm) + memset (ptm, 0xff, sizeof (*ptm)); + if (!ptm || !pt) + { + errno = EINVAL; + return EINVAL; + } + if ((ltm = _localtime32 (pt)) == NULL) + return errno; + *ptm = *ltm; + return 0; +} diff --git a/libc/mingw/secapi/_localtime64_s.c b/libc/mingw/secapi/_localtime64_s.c new file mode 100644 index 0000000000..bff0868ba1 --- /dev/null +++ b/libc/mingw/secapi/_localtime64_s.c @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_localtime64_s (struct tm *, const __time64_t *); +static errno_t __cdecl _stub (struct tm *, const __time64_t *); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_localtime64_s))(struct tm *, const __time64_t *) = + _stub; + +static errno_t __cdecl +_stub (struct tm *ptm, const __time64_t *pt) +{ + errno_t __cdecl (*f)(struct tm *, const __time64_t *) = __MINGW_IMP_SYMBOL(_localtime64_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(struct tm *, const __time64_t *)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_localtime64_s"); + if (!f) + f = _int_localtime64_s; + __MINGW_IMP_SYMBOL(_localtime64_s) = f; + } + return (*f)(ptm, pt); +} + +errno_t __cdecl +_localtime64_s (struct tm *ptm, const __time64_t *pt) +{ + return _stub (ptm, pt); +} + +static errno_t __cdecl +_int_localtime64_s (struct tm *ptm, const __time64_t *pt) +{ + struct tm *ltm; + + if (ptm) + memset (ptm, 0xff, sizeof (*ptm)); + if (!ptm || !pt) + { + errno = EINVAL; + return EINVAL; + } + if ((ltm = _localtime64 (pt)) == NULL) + return errno; + *ptm = *ltm; + return 0; +} diff --git a/libc/mingw/secapi/_mktemp_s.c b/libc/mingw/secapi/_mktemp_s.c new file mode 100644 index 0000000000..01484d9384 --- /dev/null +++ b/libc/mingw/secapi/_mktemp_s.c @@ -0,0 +1,54 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_mktemp_s (char *, size_t); +static errno_t __cdecl _stub (char *, size_t); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_mktemp_s))(char *, size_t) = + _stub; + +static errno_t __cdecl +_stub (char *d, size_t dn) +{ + errno_t __cdecl (*f)(char *, size_t) = __MINGW_IMP_SYMBOL(_mktemp_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(char *, size_t)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_mktemp_s"); + if (!f) + f = _int_mktemp_s; + __MINGW_IMP_SYMBOL(_mktemp_s) = f; + } + return (*f)(d, dn); +} + +errno_t __cdecl +_mktemp_s (char *d, size_t dn) +{ + return _stub (d, dn); +} + +static errno_t __cdecl +_int_mktemp_s (char *d, size_t dn) +{ + size_t sz; + if (!d || !dn) + { + _mktemp (NULL); + return EINVAL; + } + sz = strnlen (d, dn); + if (sz >= dn || sz < 6) + { + d[0] = 0; + _mktemp (NULL); + return EINVAL; + } + if (_mktemp (d) != NULL) + return 0; + return errno; +} diff --git a/libc/mingw/secapi/_sopen_s.c b/libc/mingw/secapi/_sopen_s.c new file mode 100644 index 0000000000..b4f8f6af5b --- /dev/null +++ b/libc/mingw/secapi/_sopen_s.c @@ -0,0 +1,42 @@ +#include +#include +#include +#include + +static errno_t __cdecl _int_sopen_s(int *, const char *, int, int, int); +static errno_t __cdecl _stub(int *, const char *, int, int, int); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_sopen_s))(int *, const char *, int, int, int) = _stub; + +static errno_t __cdecl +_stub (int* pfh, const char *filename, int oflag, int shflag, int pmode) +{ + errno_t __cdecl (*f)(int *, const char *, int, int, int) = __MINGW_IMP_SYMBOL(_sopen_s); + + if (f == _stub) { + f = (errno_t __cdecl (*)(int *, const char *, int, int, int)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_sopen_s"); + if (f == NULL) + f = _int_sopen_s; + __MINGW_IMP_SYMBOL(_sopen_s) = f; + } + + return (*f)(pfh, filename, oflag, shflag, pmode); +} + +static errno_t __cdecl _int_sopen_s(int* pfh, const char *filename, int oflag, int shflag, int pmode) +{ + if (pfh == NULL || filename == NULL) { + if (pfh != NULL) *pfh = -1; + errno = EINVAL; + return EINVAL; + } + + *pfh = _sopen(filename, oflag, shflag, pmode); + return errno; +} + +errno_t __cdecl _sopen_s(int* pfh, const char *filename, int oflag, int shflag, int pmode) +{ + return _stub (pfh, filename, oflag, shflag, pmode); +} diff --git a/libc/mingw/secapi/_strdate_s.c b/libc/mingw/secapi/_strdate_s.c new file mode 100644 index 0000000000..b62dec7521 --- /dev/null +++ b/libc/mingw/secapi/_strdate_s.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_strdate_s (char *, size_t); +static errno_t __cdecl _stub (char *, size_t); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_strdate_s))(char *, size_t) = + _stub; + +static errno_t __cdecl +_stub (char *d, size_t dn) +{ + errno_t __cdecl (*f)(char *, size_t) = __MINGW_IMP_SYMBOL(_strdate_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(char *, size_t)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_strdate_s"); + if (!f) + f = _int_strdate_s; + __MINGW_IMP_SYMBOL(_strdate_s) = f; + } + return (*f)(d, dn); +} + +errno_t __cdecl +_strdate_s (char *d, size_t dn) +{ + return _stub (d, dn); +} + +static errno_t __cdecl +_int_strdate_s (char *d, size_t dn) +{ + SYSTEMTIME dt; + + if (!d || !dn) + { + errno = EINVAL; + return EINVAL; + } + + d[0] = 0; + + if (dn < 9) + { + errno = ERANGE; + return ERANGE; + } + + GetLocalTime (&dt); + dt.wYear %= 100; + + d[0] = (char) (dt.wMonth / 10 + '0'); + d[1] = (char) (dt.wMonth % 10 + '0'); + d[2] = '/'; + d[3] = (char) (dt.wDay / 10 + '0'); + d[4] = (char) (dt.wDay % 10 + '0'); + d[5] = '/'; + d[6] = (char) (dt.wYear / 10 + '0'); + d[7] = (char) (dt.wYear % 10 + '0'); + d[8] = 0; + + return 0; +} diff --git a/libc/mingw/secapi/_strtime_s.c b/libc/mingw/secapi/_strtime_s.c new file mode 100644 index 0000000000..b66e3f95a8 --- /dev/null +++ b/libc/mingw/secapi/_strtime_s.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_strtime_s (char *, size_t); +static errno_t __cdecl _stub (char *, size_t); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_strtime_s))(char *, size_t) = + _stub; + +static errno_t __cdecl +_stub (char *d, size_t dn) +{ + errno_t __cdecl (*f)(char *, size_t) = __MINGW_IMP_SYMBOL(_strtime_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(char *, size_t)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_strtime_s"); + if (!f) + f = _int_strtime_s; + __MINGW_IMP_SYMBOL(_strtime_s) = f; + } + return (*f)(d, dn); +} + +errno_t __cdecl +_strtime_s (char *d, size_t dn) +{ + return _stub (d, dn); +} + +static errno_t __cdecl +_int_strtime_s (char *d, size_t dn) +{ + SYSTEMTIME dt; + int hours, minutes, seconds; + + if (!d || !dn) + { + errno = EINVAL; + return EINVAL; + } + + d[0] = 0; + + if (dn < 9) + { + errno = ERANGE; + return ERANGE; + } + + GetLocalTime (&dt); + dt.wYear %= 100; + + hours = dt.wHour; + minutes = dt.wMinute; + seconds = dt.wSecond; + + d[2] = d[5] = ':'; + d[0] = (char) (hours / 10 + '0'); + d[1] = (char) (hours % 10 + '0'); + d[3] = (char) (minutes / 10 + '0'); + d[4] = (char) (minutes % 10 + '0'); + d[6] = (char) (seconds / 10 + '0'); + d[7] = (char) (seconds % 10 + '0'); + d[8] = 0; + + return 0; +} diff --git a/libc/mingw/secapi/_umask_s.c b/libc/mingw/secapi/_umask_s.c new file mode 100644 index 0000000000..75e8ddbb46 --- /dev/null +++ b/libc/mingw/secapi/_umask_s.c @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_umask_s (int, int *); +static errno_t __cdecl _stub (int, int *); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_umask_s))(int, int *) = + _stub; + +static errno_t __cdecl +_stub (int m, int *pold) +{ + errno_t __cdecl (*f)(int, int *) = __MINGW_IMP_SYMBOL(_umask_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(int, int *)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_umask_s"); + if (!f) + f = _int_umask_s; + __MINGW_IMP_SYMBOL(_umask_s) = f; + } + return (*f)(m, pold); +} + +errno_t __cdecl +_umask_s (int m, int *pold) +{ + return _stub (m, pold); +} + +static errno_t __cdecl +_int_umask_s (int m, int *pold) +{ + if (!pold) + { + errno = EINVAL; + return EINVAL; + } + *pold = _umask (m); + return 0; +} diff --git a/libc/mingw/secapi/_vcprintf_s.c b/libc/mingw/secapi/_vcprintf_s.c new file mode 100644 index 0000000000..b512bb21a9 --- /dev/null +++ b/libc/mingw/secapi/_vcprintf_s.c @@ -0,0 +1,40 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include +#include + +static int __cdecl _int_vcprintf_s (const char *, va_list); +static int __cdecl _stub (const char *, va_list); + +int __cdecl (*__MINGW_IMP_SYMBOL(_vcprintf_s))(const char *, va_list) = + _stub; + +static int __cdecl +_stub (const char *s, va_list argp) +{ + int __cdecl (*f)(const char *, va_list) = __MINGW_IMP_SYMBOL(_vcprintf_s); + + if (f == _stub) + { + f = (int __cdecl (*)(const char *, va_list)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_vcprintf_s"); + if (!f) + f = _int_vcprintf_s; + __MINGW_IMP_SYMBOL(_vcprintf_s) = f; + } + return (*f)(s, argp); +} + +int __cdecl +_vcprintf_s (const char *s, va_list argp) +{ + return _stub (s, argp); +} + +static int __cdecl +_int_vcprintf_s (const char *s, va_list argp) +{ + return _vcprintf (s, argp); +} diff --git a/libc/mingw/secapi/_vcprintf_s_l.c b/libc/mingw/secapi/_vcprintf_s_l.c new file mode 100644 index 0000000000..e4c86ceb96 --- /dev/null +++ b/libc/mingw/secapi/_vcprintf_s_l.c @@ -0,0 +1,40 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include +#include + +static int __cdecl _int_vcprintf_s_l (const char *, _locale_t, va_list); +static int __cdecl _stub (const char *, _locale_t, va_list); + +int __cdecl (*__MINGW_IMP_SYMBOL(_vcprintf_s_l))(const char *, _locale_t, va_list) = + _stub; + +static int __cdecl +_stub (const char *s, _locale_t loc, va_list argp) +{ + int __cdecl (*f)(const char *, _locale_t, va_list) = __MINGW_IMP_SYMBOL(_vcprintf_s_l); + + if (f == _stub) + { + f = (int __cdecl (*)(const char *, _locale_t, va_list)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_vcprintf_s_l"); + if (!f) + f = _int_vcprintf_s_l; + __MINGW_IMP_SYMBOL(_vcprintf_s_l) = f; + } + return (*f)(s, loc, argp); +} + +int __cdecl +_vcprintf_s_l (const char *s, _locale_t loc, va_list argp) +{ + return _stub (s, loc, argp); +} + +static int __cdecl +_int_vcprintf_s_l (const char *s, _locale_t loc, va_list argp) +{ + return _vcprintf_l (s, loc, argp); +} diff --git a/libc/mingw/secapi/_vcwprintf_s.c b/libc/mingw/secapi/_vcwprintf_s.c new file mode 100644 index 0000000000..e6badb1ecf --- /dev/null +++ b/libc/mingw/secapi/_vcwprintf_s.c @@ -0,0 +1,40 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include +#include + +static int __cdecl _int_vcwprintf_s (const wchar_t *, va_list); +static int __cdecl _stub (const wchar_t *, va_list); + +int __cdecl (*__MINGW_IMP_SYMBOL(_vcwprintf_s))(const wchar_t *, va_list) = + _stub; + +static int __cdecl +_stub (const wchar_t *s, va_list argp) +{ + int __cdecl (*f)(const wchar_t *, va_list) = __MINGW_IMP_SYMBOL(_vcwprintf_s); + + if (f == _stub) + { + f = (int __cdecl (*)(const wchar_t *, va_list)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_vcwprintf_s"); + if (!f) + f = _int_vcwprintf_s; + __MINGW_IMP_SYMBOL(_vcwprintf_s) = f; + } + return (*f)(s, argp); +} + +int __cdecl +_vcwprintf_s (const wchar_t *s, va_list argp) +{ + return _stub (s, argp); +} + +static int __cdecl +_int_vcwprintf_s (const wchar_t *s, va_list argp) +{ + return _vcwprintf (s, argp); +} diff --git a/libc/mingw/secapi/_vcwprintf_s_l.c b/libc/mingw/secapi/_vcwprintf_s_l.c new file mode 100644 index 0000000000..2ce1deffdf --- /dev/null +++ b/libc/mingw/secapi/_vcwprintf_s_l.c @@ -0,0 +1,40 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include +#include + +static int __cdecl _int_vcwprintf_s_l (const wchar_t *, _locale_t, va_list); +static int __cdecl _stub (const wchar_t *, _locale_t, va_list); + +int __cdecl (*__MINGW_IMP_SYMBOL(_vcwprintf_s_l))(const wchar_t *, _locale_t, va_list) = + _stub; + +static int __cdecl +_stub (const wchar_t *s, _locale_t loc, va_list argp) +{ + int __cdecl (*f)(const wchar_t *, _locale_t, va_list) = __MINGW_IMP_SYMBOL(_vcwprintf_s_l); + + if (f == _stub) + { + f = (int __cdecl (*)(const wchar_t *, _locale_t, va_list)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_vcwprintf_s_l"); + if (!f) + f = _int_vcwprintf_s_l; + __MINGW_IMP_SYMBOL(_vcwprintf_s_l) = f; + } + return (*f)(s, loc, argp); +} + +int __cdecl +_vcwprintf_s_l (const wchar_t *s, _locale_t loc, va_list argp) +{ + return _stub (s, loc, argp); +} + +static int __cdecl +_int_vcwprintf_s_l (const wchar_t *s, _locale_t loc, va_list argp) +{ + return _vcwprintf_l (s, loc, argp); +} diff --git a/libc/mingw/secapi/_vscprintf_p.c b/libc/mingw/secapi/_vscprintf_p.c new file mode 100644 index 0000000000..c7ee3cc87f --- /dev/null +++ b/libc/mingw/secapi/_vscprintf_p.c @@ -0,0 +1,9 @@ +#define MINGW_HAS_SECURE_API 1 +#include + +int __cdecl _vscprintf_p(const char *format, va_list arglist) +{ + return _vscprintf_p_l(format, NULL, arglist); +} + +int __cdecl (*__MINGW_IMP_SYMBOL(_vscprintf_p))(const char *, va_list) = _vscprintf_p; diff --git a/libc/mingw/secapi/_vscwprintf_p.c b/libc/mingw/secapi/_vscwprintf_p.c new file mode 100644 index 0000000000..498bc1cf48 --- /dev/null +++ b/libc/mingw/secapi/_vscwprintf_p.c @@ -0,0 +1,9 @@ +#define MINGW_HAS_SECURE_API 1 +#include + +int __cdecl _vscwprintf_p(const wchar_t *format, va_list arglist) +{ + return _vscwprintf_p_l(format, NULL, arglist); +} + +int __cdecl (*__MINGW_IMP_SYMBOL(_vscwprintf_p))(const wchar_t *, va_list) = _vscwprintf_p; diff --git a/libc/mingw/secapi/_vswprintf_p.c b/libc/mingw/secapi/_vswprintf_p.c new file mode 100644 index 0000000000..4823c81d69 --- /dev/null +++ b/libc/mingw/secapi/_vswprintf_p.c @@ -0,0 +1,9 @@ +#define MINGW_HAS_SECURE_API 1 +#include + +int __cdecl _vswprintf_p(wchar_t *_DstBuf, size_t _MaxCount, const wchar_t *_Format, va_list _ArgList) +{ + return _vswprintf_p_l(_DstBuf, _MaxCount, _Format, NULL, _ArgList); +} + +int __cdecl (*__MINGW_IMP_SYMBOL(_vswprintf_p))(wchar_t*,size_t,const wchar_t*,va_list) = _vswprintf_p; diff --git a/libc/mingw/secapi/_waccess_s.c b/libc/mingw/secapi/_waccess_s.c new file mode 100644 index 0000000000..4ca83f4dd4 --- /dev/null +++ b/libc/mingw/secapi/_waccess_s.c @@ -0,0 +1,47 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_waccess_s (const wchar_t *, int); +static errno_t __cdecl _stub (const wchar_t *, int); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_waccess_s))(const wchar_t *, int) = + _stub; + +static errno_t __cdecl +_stub (const wchar_t *s, int m) +{ + errno_t __cdecl (*f)(const wchar_t *, int) = __MINGW_IMP_SYMBOL(_waccess_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(const wchar_t *, int)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_waccess_s"); + if (!f) + f = _int_waccess_s; + __MINGW_IMP_SYMBOL(_waccess_s) = f; + } + return (*f)(s, m); +} + +errno_t __cdecl +_waccess_s (const wchar_t *s, int m) +{ + return _stub (s, m); +} + +static errno_t __cdecl +_int_waccess_s (const wchar_t *s, int m) +{ + if (!s || (m & ~6) != 0) + { + _waccess (NULL, m); + return EINVAL; + } + if (!_waccess (s, m)) + return 0; + return errno; +} diff --git a/libc/mingw/secapi/_wasctime_s.c b/libc/mingw/secapi/_wasctime_s.c new file mode 100644 index 0000000000..6b414ee9dd --- /dev/null +++ b/libc/mingw/secapi/_wasctime_s.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_wasctime_s (wchar_t *, size_t, const struct tm *); +static errno_t __cdecl _stub (wchar_t *, size_t, const struct tm *); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_wasctime_s))(wchar_t *, size_t, const struct tm *) = + _stub; + +static errno_t __cdecl +_stub (wchar_t *d, size_t dn, const struct tm *pt) +{ + errno_t __cdecl (*f)(wchar_t *, size_t, const struct tm *) = __MINGW_IMP_SYMBOL(_wasctime_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(wchar_t *, size_t, const struct tm *)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_wasctime_s"); + if (!f) + f = _int_wasctime_s; + __MINGW_IMP_SYMBOL(_wasctime_s) = f; + } + return (*f)(d, dn, pt); +} + +errno_t __cdecl +_wasctime_s (wchar_t *d, size_t dn, const struct tm *pt) +{ + return _stub (d, dn, pt); +} + +static errno_t __cdecl +_int_wasctime_s (wchar_t *d, size_t dn, const struct tm *pt) +{ + wchar_t *tmp; + size_t i; + + if (d && dn) + d[0] = 0; + if (!d || dn < 26 || !pt || (tmp = _wasctime (pt)) == NULL) + { + errno = EINVAL; + return EINVAL; + } + for (i = 0; tmp[i] != 0; i++) + d[i] = tmp[i]; + d[i] = 0; + return 0; +} diff --git a/libc/mingw/secapi/_wctime32_s.c b/libc/mingw/secapi/_wctime32_s.c new file mode 100644 index 0000000000..27c414b161 --- /dev/null +++ b/libc/mingw/secapi/_wctime32_s.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_wctime32_s (wchar_t *, size_t, const __time32_t *); +static errno_t __cdecl _stub (wchar_t *, size_t, const __time32_t *); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_wctime32_s))(wchar_t *, size_t, const __time32_t *) = + _stub; + +static errno_t __cdecl +_stub (wchar_t *d, size_t dn, const __time32_t *pt) +{ + errno_t __cdecl (*f)(wchar_t*,size_t, const __time32_t *) = __MINGW_IMP_SYMBOL(_wctime32_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(wchar_t *, size_t, const __time32_t *)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_wctime32_s"); + if (!f) + f = _int_wctime32_s; + __MINGW_IMP_SYMBOL(_wctime32_s) = f; + } + return (*f)(d, dn, pt); +} + +errno_t __cdecl +_wctime32_s (wchar_t *d, size_t dn, const __time32_t *pt) +{ + return _stub (d, dn, pt); +} + +static errno_t __cdecl +_int_wctime32_s (wchar_t *d, size_t dn, const __time32_t *pt) +{ + struct tm ltm; + errno_t e; + + if (!d || !dn) + { + errno = EINVAL; + return EINVAL; + } + d[0] = 0; + if (!pt) + { + errno = EINVAL; + return EINVAL; + } + + if ((e = _localtime32_s (<m, pt)) != 0) + return e; + return _wasctime_s (d, dn, <m); +} diff --git a/libc/mingw/secapi/_wctime64_s.c b/libc/mingw/secapi/_wctime64_s.c new file mode 100644 index 0000000000..bce40fd227 --- /dev/null +++ b/libc/mingw/secapi/_wctime64_s.c @@ -0,0 +1,56 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_wctime64_s (wchar_t *, size_t, const __time64_t *); +static errno_t __cdecl _stub (wchar_t *, size_t, const __time64_t *); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_wctime64_s))(wchar_t *, size_t, const __time64_t *) = + _stub; + +static errno_t __cdecl +_stub (wchar_t *d, size_t dn, const __time64_t *pt) +{ + errno_t __cdecl (*f)(wchar_t*,size_t, const __time64_t *) = __MINGW_IMP_SYMBOL(_wctime64_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(wchar_t *, size_t, const __time64_t *)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_wctime64_s"); + if (!f) + f = _int_wctime64_s; + __MINGW_IMP_SYMBOL(_wctime64_s) = f; + } + return (*f)(d, dn, pt); +} + +errno_t __cdecl +_wctime64_s (wchar_t *d, size_t dn, const __time64_t *pt) +{ + return _stub (d, dn, pt); +} + +static errno_t __cdecl +_int_wctime64_s (wchar_t *d, size_t dn, const __time64_t *pt) +{ + struct tm ltm; + errno_t e; + + if (!d || !dn) + { + errno = EINVAL; + return EINVAL; + } + d[0] = 0; + if (!pt) + { + errno = EINVAL; + return EINVAL; + } + + if ((e = _localtime64_s (<m, pt)) != 0) + return e; + return _wasctime_s (d, dn, <m); +} diff --git a/libc/mingw/secapi/_wmktemp_s.c b/libc/mingw/secapi/_wmktemp_s.c new file mode 100644 index 0000000000..3cbf0c7809 --- /dev/null +++ b/libc/mingw/secapi/_wmktemp_s.c @@ -0,0 +1,55 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_wmktemp_s (wchar_t *, size_t); +static errno_t __cdecl _stub (wchar_t *, size_t); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_wmktemp_s))(wchar_t *, size_t) = + _stub; + +static errno_t __cdecl +_stub (wchar_t *d, size_t dn) +{ + errno_t __cdecl (*f)(wchar_t *, size_t) = __MINGW_IMP_SYMBOL(_wmktemp_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(wchar_t *, size_t)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_wmktemp_s"); + if (!f) + f = _int_wmktemp_s; + __MINGW_IMP_SYMBOL(_wmktemp_s) = f; + } + return (*f)(d, dn); +} + +errno_t __cdecl +_wmktemp_s (wchar_t *d, size_t dn) +{ + return _stub (d, dn); +} + +static errno_t __cdecl +_int_wmktemp_s (wchar_t *d, size_t dn) +{ + size_t sz; + if (!d || !dn) + { + _wmktemp (NULL); + return EINVAL; + } + sz = wcsnlen (d, dn); + if (sz >= dn || sz < 6) + { + d[0] = 0; + _wmktemp (NULL); + return EINVAL; + } + if (_wmktemp (d) != NULL) + return 0; + return errno; +} diff --git a/libc/mingw/secapi/_wstrdate_s.c b/libc/mingw/secapi/_wstrdate_s.c new file mode 100644 index 0000000000..e8ec1d446e --- /dev/null +++ b/libc/mingw/secapi/_wstrdate_s.c @@ -0,0 +1,68 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_wstrdate_s (wchar_t *, size_t); +static errno_t __cdecl _stub (wchar_t *, size_t); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_wstrdate_s))(wchar_t *, size_t) = + _stub; + +static errno_t __cdecl +_stub (wchar_t *d, size_t dn) +{ + errno_t __cdecl (*f)(wchar_t *, size_t) = __MINGW_IMP_SYMBOL(_wstrdate_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(wchar_t *, size_t)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_wstrdate_s"); + if (!f) + f = _int_wstrdate_s; + __MINGW_IMP_SYMBOL(_wstrdate_s) = f; + } + return (*f)(d, dn); +} + +errno_t __cdecl +_wstrdate_s (wchar_t *d, size_t dn) +{ + return _stub (d, dn); +} + +static errno_t __cdecl +_int_wstrdate_s (wchar_t *d, size_t dn) +{ + SYSTEMTIME dt; + + if (!d || !dn) + { + errno = EINVAL; + return EINVAL; + } + + d[0] = 0; + + if (dn < 9) + { + errno = ERANGE; + return ERANGE; + } + + GetLocalTime (&dt); + dt.wYear %= 100; + + d[0] = (wchar_t) (dt.wMonth / 10 + '0'); + d[1] = (wchar_t) (dt.wMonth % 10 + '0'); + d[2] = '/'; + d[3] = (wchar_t) (dt.wDay / 10 + '0'); + d[4] = (wchar_t) (dt.wDay % 10 + '0'); + d[5] = '/'; + d[6] = (wchar_t) (dt.wYear / 10 + '0'); + d[7] = (wchar_t) (dt.wYear % 10 + '0'); + d[8] = 0; + + return 0; +} diff --git a/libc/mingw/secapi/_wstrtime_s.c b/libc/mingw/secapi/_wstrtime_s.c new file mode 100644 index 0000000000..ffb8a3e96f --- /dev/null +++ b/libc/mingw/secapi/_wstrtime_s.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_wstrtime_s (wchar_t *, size_t); +static errno_t __cdecl _stub (wchar_t *, size_t); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(_wstrtime_s))(wchar_t *, size_t) = + _stub; + +static errno_t __cdecl +_stub (wchar_t *d, size_t dn) +{ + errno_t __cdecl (*f)(wchar_t *, size_t) = __MINGW_IMP_SYMBOL(_wstrtime_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(wchar_t *, size_t)) + GetProcAddress (__mingw_get_msvcrt_handle (), "_wstrtime_s"); + if (!f) + f = _int_wstrtime_s; + __MINGW_IMP_SYMBOL(_wstrtime_s) = f; + } + return (*f)(d, dn); +} + +errno_t __cdecl +_wstrtime_s (wchar_t *d, size_t dn) +{ + return _stub (d, dn); +} + +static errno_t __cdecl +_int_wstrtime_s (wchar_t *d, size_t dn) +{ + SYSTEMTIME dt; + int hours, minutes, seconds; + + if (!d || !dn) + { + errno = EINVAL; + return EINVAL; + } + + d[0] = 0; + + if (dn < 9) + { + errno = ERANGE; + return ERANGE; + } + + GetLocalTime (&dt); + + hours = dt.wHour; + minutes = dt.wMinute; + seconds = dt.wSecond; + + d[2] = d[5] = ':'; + d[0] = (wchar_t) (hours / 10 + '0'); + d[1] = (wchar_t) (hours % 10 + '0'); + d[3] = (wchar_t) (minutes / 10 + '0'); + d[4] = (wchar_t) (minutes % 10 + '0'); + d[6] = (wchar_t) (seconds / 10 + '0'); + d[7] = (wchar_t) (seconds % 10 + '0'); + d[8] = 0; + + return 0; +} diff --git a/libc/mingw/secapi/asctime_s.c b/libc/mingw/secapi/asctime_s.c new file mode 100644 index 0000000000..aeb16e3bcf --- /dev/null +++ b/libc/mingw/secapi/asctime_s.c @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_asctime_s (char *, size_t, const struct tm *); +static errno_t __cdecl _stub (char *, size_t, const struct tm *); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(asctime_s))(char *, size_t, const struct tm *) = + _stub; + +static errno_t __cdecl +_stub (char *d, size_t dn, const struct tm *pt) +{ + errno_t __cdecl (*f)(char *, size_t, const struct tm *) = __MINGW_IMP_SYMBOL(asctime_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(char *, size_t, const struct tm *)) + GetProcAddress (__mingw_get_msvcrt_handle (), "asctime_s"); + if (!f) + f = _int_asctime_s; + __MINGW_IMP_SYMBOL(asctime_s) = f; + } + return (*f)(d, dn, pt); +} + +errno_t __cdecl +asctime_s (char *d, size_t dn, const struct tm *pt) +{ + return _stub (d, dn, pt); +} + +static errno_t __cdecl +_int_asctime_s (char *d, size_t dn, const struct tm *pt) +{ + char *tmp; + size_t i; + + if (d && dn) + d[0] = 0; + if (!d || dn < 26 || !pt || (tmp = asctime (pt)) == NULL) + { + errno = EINVAL; + return EINVAL; + } + for (i = 0; tmp[i] != 0; i++) + d[i] = tmp[i]; + d[i] = 0; + return 0; +} diff --git a/libc/mingw/secapi/memcpy_s.c b/libc/mingw/secapi/memcpy_s.c new file mode 100644 index 0000000000..013eff05c5 --- /dev/null +++ b/libc/mingw/secapi/memcpy_s.c @@ -0,0 +1,59 @@ +#include +#include +#include +#include + +static errno_t __cdecl _int_memcpy_s (void *, size_t, const void *, size_t); +static errno_t __cdecl _stub (void *, size_t, const void *, size_t); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(memcpy_s))(void *, size_t, const void *, size_t) = + _stub; + +static errno_t __cdecl +_stub (void *d, size_t dn, const void *s, size_t n) +{ + errno_t __cdecl (*f)(void *, size_t, const void *, size_t) = __MINGW_IMP_SYMBOL(memcpy_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(void *, size_t, const void *, size_t)) + GetProcAddress (__mingw_get_msvcrt_handle (), "memcpy_s"); + if (!f) + f = _int_memcpy_s; + __MINGW_IMP_SYMBOL(memcpy_s) = f; + } + return (*f)(d, dn, s, n); +} + +errno_t __cdecl +memcpy_s (void *d, size_t dn, const void *s, size_t n) +{ + return _stub (d, dn, s, n); +} + +static errno_t __cdecl +_int_memcpy_s (void *d, size_t dn, const void *s, size_t n) +{ + if (!n) + return 0; + + if (!d || !s) + { + if (d) + memset (d, 0, dn); + errno = EINVAL; + return EINVAL; + } + + if (dn < n) + { + memset (d, 0, dn); + + errno = ERANGE; + return ERANGE; + } + + memcpy (d, s, n); + + return 0; +} diff --git a/libc/mingw/secapi/memmove_s.c b/libc/mingw/secapi/memmove_s.c new file mode 100644 index 0000000000..170bdf32ce --- /dev/null +++ b/libc/mingw/secapi/memmove_s.c @@ -0,0 +1,60 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include + +static errno_t __cdecl _int_memmove_s (void *, size_t, const void *, size_t); +static errno_t __cdecl _stub (void *, size_t, const void *, size_t); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(memmove_s))(void *, size_t, const void *, size_t) = + _stub; + +static errno_t __cdecl +_stub (void *d, size_t dn, const void *s, size_t n) +{ + errno_t __cdecl (*f)(void *, size_t, const void *, size_t) = __MINGW_IMP_SYMBOL(memmove_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(void *, size_t, const void *, size_t)) + GetProcAddress (__mingw_get_msvcrt_handle (), "memmove_s"); + if (!f) + f = _int_memmove_s; + __MINGW_IMP_SYMBOL(memmove_s) = f; + } + return (*f)(d, dn, s, n); +} + +errno_t __cdecl +memmove_s (void *d, size_t dn, const void *s, size_t n) +{ + return _stub (d, dn, s, n); +} + +static errno_t __cdecl +_int_memmove_s (void *d, size_t dn, const void *s, size_t n) +{ + if (!n) + return 0; + + if (!d || !s) + { + if (d) + memset (d, 0, dn); + errno = EINVAL; + return EINVAL; + } + + if (dn < n) + { + memset (d, 0, dn); + + errno = ERANGE; + return ERANGE; + } + + memmove (d, s, n); + + return 0; +} diff --git a/libc/mingw/secapi/rand_s.c b/libc/mingw/secapi/rand_s.c new file mode 100644 index 0000000000..7773d65ece --- /dev/null +++ b/libc/mingw/secapi/rand_s.c @@ -0,0 +1,30 @@ +#define _CRT_RAND_S +#include +#include +#include +#include +#include + +static BOOLEAN (WINAPI *pRtlGenRandom)(void*,ULONG); + +static errno_t mingw_rand_s(unsigned int *pval) +{ + return !pval || !pRtlGenRandom || !pRtlGenRandom(pval, sizeof(*pval)) ? EINVAL : 0; +} + +static errno_t __cdecl init_rand_s(unsigned int*); + +errno_t (__cdecl *__MINGW_IMP_SYMBOL(rand_s))(unsigned int*) = init_rand_s; + +static errno_t __cdecl init_rand_s(unsigned int *val) +{ + int (__cdecl *func)(unsigned int*); + + func = (void*)GetProcAddress(__mingw_get_msvcrt_handle(), "rand_s"); + if(!func) { + func = mingw_rand_s; + pRtlGenRandom = (void*)GetProcAddress(LoadLibraryW(L"advapi32.dll"), "SystemFunction036"); + } + + return (__MINGW_IMP_SYMBOL(rand_s) = func)(val); +} diff --git a/libc/mingw/secapi/sprintf_s.c b/libc/mingw/secapi/sprintf_s.c new file mode 100644 index 0000000000..3b92d07beb --- /dev/null +++ b/libc/mingw/secapi/sprintf_s.c @@ -0,0 +1,20 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include +#include + +int __cdecl (*__MINGW_IMP_SYMBOL(sprintf_s))(char *, size_t, const char *,...) = sprintf_s; + +int __cdecl +sprintf_s (char *_DstBuf, size_t _Size, const char *_Format, ...) +{ + va_list argp; + int r; + + va_start (argp, _Format); + r = vsprintf_s (_DstBuf, _Size, _Format, argp); + va_end (argp); + return r; +} diff --git a/libc/mingw/secapi/strerror_s.c b/libc/mingw/secapi/strerror_s.c new file mode 100644 index 0000000000..148236d393 --- /dev/null +++ b/libc/mingw/secapi/strerror_s.c @@ -0,0 +1,53 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_strerror_s (char *, size_t, int); +static errno_t __cdecl _stub (char *, size_t, int); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(strerror_s))(char *, size_t, int) = _stub; + +static errno_t __cdecl +_stub (char *buffer, size_t numberOfElements, int errnum) +{ + errno_t __cdecl (*f)(char *, size_t, int) = __MINGW_IMP_SYMBOL(strerror_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(char *, size_t, int)) + GetProcAddress (__mingw_get_msvcrt_handle (), "strerror_s"); + if (!f) + f = _int_strerror_s; + __MINGW_IMP_SYMBOL(strerror_s) = f; + } + return (*f)(buffer, numberOfElements, errnum); +} + +errno_t __cdecl +strerror_s (char *buffer, size_t numberOfElements, int errnum) +{ + return _stub (buffer, numberOfElements, errnum); +} + +static errno_t __cdecl +_int_strerror_s (char *buffer, size_t numberOfElements, int errnum) +{ + char *errmsg = strerror(errnum); + + if (!errmsg || !buffer || numberOfElements == 0) + { + errno = EINVAL; + return EINVAL; + } + + if (sprintf_s(buffer, numberOfElements, "%s", errmsg) == -1) + { + errno = EINVAL; + return EINVAL; + } + + return 0; +} diff --git a/libc/mingw/secapi/vsprintf_s.c b/libc/mingw/secapi/vsprintf_s.c new file mode 100644 index 0000000000..96a7680830 --- /dev/null +++ b/libc/mingw/secapi/vsprintf_s.c @@ -0,0 +1,41 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include +#include +#include + +static int __cdecl _int_vsprintf_s (char *, size_t, const char *, va_list); +static int __cdecl _stub (char *, size_t, const char *, va_list); + +int __cdecl (*__MINGW_IMP_SYMBOL(vsprintf_s))(char *, size_t, const char *, va_list) = + _stub; + +static int __cdecl +_stub (char *_DstBuf, size_t _Size, const char *_Format, va_list _ArgList) +{ + int __cdecl (*f)(char *, size_t, const char *, va_list) = __MINGW_IMP_SYMBOL(vsprintf_s); + + if (f == _stub) + { + f = (int __cdecl (*)(char *, size_t, const char *, va_list)) + GetProcAddress (__mingw_get_msvcrt_handle (), "vsprintf_s"); + if (!f) + f = _int_vsprintf_s; + __MINGW_IMP_SYMBOL(vsprintf_s) = f; + } + return (*f)(_DstBuf, _Size, _Format, _ArgList); +} + +int __cdecl +vsprintf_s (char *_DstBuf, size_t _Size, const char *_Format, va_list _ArgList) +{ + return _stub (_DstBuf, _Size, _Format, _ArgList); +} + +static int __cdecl +_int_vsprintf_s (char *_DstBuf, size_t _Size, const char *_Format, va_list _ArgList) +{ + return __ms_vsnprintf (_DstBuf, _Size, _Format, _ArgList); +} diff --git a/libc/mingw/secapi/wmemcpy_s.c b/libc/mingw/secapi/wmemcpy_s.c new file mode 100644 index 0000000000..bb59bdca80 --- /dev/null +++ b/libc/mingw/secapi/wmemcpy_s.c @@ -0,0 +1,61 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_wmemcpy_s (wchar_t *, size_t, const wchar_t *, size_t); +static errno_t __cdecl _stub (wchar_t *, size_t, const wchar_t *, size_t); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(wmemcpy_s))(wchar_t *, size_t, const wchar_t *, size_t) = + _stub; + +static errno_t __cdecl +_stub (wchar_t *d, size_t dn, const wchar_t *s, size_t n) +{ + errno_t __cdecl (*f)(wchar_t *, size_t, const wchar_t *, size_t) = __MINGW_IMP_SYMBOL(wmemcpy_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(wchar_t *, size_t, const wchar_t *, size_t)) + GetProcAddress (__mingw_get_msvcrt_handle (), "wmemcpy_s"); + if (!f) + f = _int_wmemcpy_s; + __MINGW_IMP_SYMBOL(wmemcpy_s) = f; + } + return (*f)(d, dn, s, n); +} + +errno_t __cdecl +wmemcpy_s (wchar_t *d, size_t dn, const wchar_t *s, size_t n) +{ + return _stub (d, dn, s, n); +} + +static errno_t __cdecl +_int_wmemcpy_s (wchar_t *d, size_t dn, const wchar_t *s, size_t n) +{ + if (!n) + return 0; + + if (!d || !s) + { + if (d) + memset (d, 0, dn * sizeof (wchar_t)); + errno = EINVAL; + return EINVAL; + } + + if (dn < n) + { + memset (d, 0, dn * sizeof (wchar_t)); + + errno = ERANGE; + return ERANGE; + } + + memcpy (d, s, n * sizeof (wchar_t)); + + return 0; +} diff --git a/libc/mingw/secapi/wmemmove_s.c b/libc/mingw/secapi/wmemmove_s.c new file mode 100644 index 0000000000..788fa7e461 --- /dev/null +++ b/libc/mingw/secapi/wmemmove_s.c @@ -0,0 +1,61 @@ +#define MINGW_HAS_SECURE_API 1 +#include +#include +#include +#include +#include + +static errno_t __cdecl _int_wmemmove_s (wchar_t *, size_t, const wchar_t*, size_t); +static errno_t __cdecl _stub (wchar_t *, size_t, const wchar_t *, size_t); + +errno_t __cdecl (*__MINGW_IMP_SYMBOL(wmemmove_s))(wchar_t *, size_t, const wchar_t *, size_t) = + _stub; + +static errno_t __cdecl +_stub (wchar_t *d, size_t dn, const wchar_t *s, size_t n) +{ + errno_t __cdecl (*f)(wchar_t *, size_t, const wchar_t *, size_t) = __MINGW_IMP_SYMBOL(wmemmove_s); + + if (f == _stub) + { + f = (errno_t __cdecl (*)(wchar_t *, size_t, const wchar_t *, size_t)) + GetProcAddress (__mingw_get_msvcrt_handle (), "wmemmove_s"); + if (!f) + f = _int_wmemmove_s; + __MINGW_IMP_SYMBOL(wmemmove_s) = f; + } + return (*f)(d, dn, s, n); +} + +errno_t __cdecl +wmemmove_s (wchar_t *d, size_t dn, const wchar_t *s, size_t n) +{ + return _stub (d, dn, s, n); +} + +static errno_t __cdecl +_int_wmemmove_s (wchar_t *d, size_t dn, const wchar_t *s, size_t n) +{ + if (!n) + return 0; + + if (!d || !s) + { + if (d) + memset (d, 0, dn * sizeof (wchar_t)); + errno = EINVAL; + return EINVAL; + } + + if (dn < n) + { + memset (d, 0, dn * sizeof (wchar_t)); + + errno = ERANGE; + return ERANGE; + } + + memmove (d, s, n * sizeof (wchar_t)); + + return 0; +} diff --git a/libc/mingw/stdio/acrt_iob_func.c b/libc/mingw/stdio/acrt_iob_func.c new file mode 100644 index 0000000000..085a5fa739 --- /dev/null +++ b/libc/mingw/stdio/acrt_iob_func.c @@ -0,0 +1,15 @@ +/** + * This file has no copyright assigned and is placed in the Public Domain. + * This file is part of the mingw-w64 runtime package. + * No warranty is given; refer to the file DISCLAIMER.PD within this package. + */ + +#include + +FILE *__cdecl __acrt_iob_func(unsigned index) +{ + return &(__iob_func()[index]); +} + +typedef FILE *__cdecl (*_f__acrt_iob_func)(unsigned index); +_f__acrt_iob_func __MINGW_IMP_SYMBOL(__acrt_iob_func) = __acrt_iob_func; diff --git a/libc/mingw/stdio/mingw_lock.c b/libc/mingw/stdio/mingw_lock.c new file mode 100644 index 0000000000..ebc3c256fe --- /dev/null +++ b/libc/mingw/stdio/mingw_lock.c @@ -0,0 +1,102 @@ +#define _CRTIMP +#include +#include +#include "internal.h" + +/*** + * Copy of MS functions _lock_file, _unlock_file which are missing from + * msvcrt.dll and msvcr80.dll. They are needed to atomic/lock stdio + * functions (printf, fprintf, vprintf, vfprintf). We need exactly the same + * lock that MS uses in msvcrt.dll because we can mix mingw-w64 code with + * original MS functions (puts, fputs for example). +***/ + + +_CRTIMP void __cdecl _lock(int locknum); +_CRTIMP void __cdecl _unlock(int locknum); +#define _STREAM_LOCKS 16 +#define _IOLOCKED 0x8000 + + +/*** +* _lock_file - Lock a FILE +* +*Purpose: +* Assert the lock for a stdio-level file +* +*Entry: +* pf = __piob[] entry (pointer to a FILE or _FILEX) +* +*Exit: +* +*Exceptions: +* +*******************************************************************************/ + +void __cdecl _lock_file( FILE *pf ) +{ + /* + * The way the FILE (pointed to by pf) is locked depends on whether + * it is part of _iob[] or not + */ + if ( (pf >= __acrt_iob_func(0)) && (pf <= __acrt_iob_func(_IOB_ENTRIES-1)) ) + { + /* + * FILE lies in _iob[] so the lock lies in _locktable[]. + */ + _lock( _STREAM_LOCKS + (int)(pf - __acrt_iob_func(0)) ); + /* We set _IOLOCKED to indicate we locked the stream */ + pf->_flag |= _IOLOCKED; + } + else + /* + * Not part of _iob[]. Therefore, *pf is a _FILEX and the + * lock field of the struct is an initialized critical + * section. + */ + EnterCriticalSection( &(((_FILEX *)pf)->lock) ); +} + +void *__MINGW_IMP_SYMBOL(_lock_file) = _lock_file; + + +/*** +* _unlock_file - Unlock a FILE +* +*Purpose: +* Release the lock for a stdio-level file +* +*Entry: +* pf = __piob[] entry (pointer to a FILE or _FILEX) +* +*Exit: +* +*Exceptions: +* +*******************************************************************************/ + +void __cdecl _unlock_file( FILE *pf ) +{ + /* + * The way the FILE (pointed to by pf) is unlocked depends on whether + * it is part of _iob[] or not + */ + if ( (pf >= __acrt_iob_func(0)) && (pf <= __acrt_iob_func(_IOB_ENTRIES-1)) ) + { + /* + * FILE lies in _iob[] so the lock lies in _locktable[]. + * We reset _IOLOCKED to indicate we unlock the stream. + */ + pf->_flag &= ~_IOLOCKED; + _unlock( _STREAM_LOCKS + (int)(pf - __acrt_iob_func(0)) ); + } + else + /* + * Not part of _iob[]. Therefore, *pf is a _FILEX and the + * lock field of the struct is an initialized critical + * section. + */ + LeaveCriticalSection( &(((_FILEX *)pf)->lock) ); +} + +void *__MINGW_IMP_SYMBOL(_unlock_file) = _unlock_file; diff --git a/src/ir.cpp b/src/ir.cpp index 94307627a1..616bb23132 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -15027,9 +15027,10 @@ static IrInstruction *ir_analyze_instruction_export(IrAnalyze *ira, IrInstructio break; } } break; + case ZigTypeIdInt: + break; case ZigTypeIdVoid: case ZigTypeIdBool: - case ZigTypeIdInt: case ZigTypeIdFloat: case ZigTypeIdPointer: case ZigTypeIdComptimeFloat: diff --git a/src/link.cpp b/src/link.cpp index ef5db4c4ad..526f9e07f1 100644 --- a/src/link.cpp +++ b/src/link.cpp @@ -570,6 +570,96 @@ static const char *build_musl(CodeGen *parent) { return buf_ptr(&child_gen->output_file_path); } +static const char *msvcrt_common_src[] = { + "misc" OS_SEP "onexit_table.c", + "misc" OS_SEP "register_tls_atexit.c", + "stdio" OS_SEP "acrt_iob_func.c", + "misc" OS_SEP "_configthreadlocale.c", + "misc" OS_SEP "_get_current_locale.c", + "misc" OS_SEP "invalid_parameter_handler.c", + "misc" OS_SEP "output_format.c", + "misc" OS_SEP "purecall.c", + "secapi" OS_SEP "_access_s.c", + "secapi" OS_SEP "_cgets_s.c", + "secapi" OS_SEP "_cgetws_s.c", + "secapi" OS_SEP "_chsize_s.c", + "secapi" OS_SEP "_controlfp_s.c", + "secapi" OS_SEP "_cprintf_s.c", + "secapi" OS_SEP "_cprintf_s_l.c", + "secapi" OS_SEP "_ctime32_s.c", + "secapi" OS_SEP "_ctime64_s.c", + "secapi" OS_SEP "_cwprintf_s.c", + "secapi" OS_SEP "_cwprintf_s_l.c", + "secapi" OS_SEP "_gmtime32_s.c", + "secapi" OS_SEP "_gmtime64_s.c", + "secapi" OS_SEP "_localtime32_s.c", + "secapi" OS_SEP "_localtime64_s.c", + "secapi" OS_SEP "_mktemp_s.c", + "secapi" OS_SEP "_sopen_s.c", + "secapi" OS_SEP "_strdate_s.c", + "secapi" OS_SEP "_strtime_s.c", + "secapi" OS_SEP "_umask_s.c", + "secapi" OS_SEP "_vcprintf_s.c", + "secapi" OS_SEP "_vcprintf_s_l.c", + "secapi" OS_SEP "_vcwprintf_s.c", + "secapi" OS_SEP "_vcwprintf_s_l.c", + "secapi" OS_SEP "_vscprintf_p.c", + "secapi" OS_SEP "_vscwprintf_p.c", + "secapi" OS_SEP "_vswprintf_p.c", + "secapi" OS_SEP "_waccess_s.c", + "secapi" OS_SEP "_wasctime_s.c", + "secapi" OS_SEP "_wctime32_s.c", + "secapi" OS_SEP "_wctime64_s.c", + "secapi" OS_SEP "_wstrtime_s.c", + "secapi" OS_SEP "_wmktemp_s.c", + "secapi" OS_SEP "_wstrdate_s.c", + "secapi" OS_SEP "asctime_s.c", + "secapi" OS_SEP "memcpy_s.c", + "secapi" OS_SEP "memmove_s.c", + "secapi" OS_SEP "rand_s.c", + "secapi" OS_SEP "sprintf_s.c", + "secapi" OS_SEP "strerror_s.c", + "secapi" OS_SEP "vsprintf_s.c", + "secapi" OS_SEP "wmemcpy_s.c", + "secapi" OS_SEP "wmemmove_s.c", + "stdio" OS_SEP "mingw_lock.c", +}; + +static const char *msvcrt_i386_src[] = { + "misc" OS_SEP "lc_locale_func.c", + +}; + +static const char *msvcrt_other_src[] = { + "misc" OS_SEP "__p___argv.c", + "misc" OS_SEP "__p__acmdln.c", + "misc" OS_SEP "__p__fmode.c", + "misc" OS_SEP "__p__wcmdln.c", +}; + +static void add_msvcrt_os_dep(CodeGen *parent, CodeGen *child_gen, const char *src_path) { + CFile *c_file = allocate(1); + c_file->source_path = buf_ptr(buf_sprintf("%s" OS_SEP "libc" OS_SEP "mingw" OS_SEP "%s", + buf_ptr(parent->zig_lib_dir), src_path)); + c_file->args.append("-DHAVE_CONFIG_H"); + c_file->args.append("-D__LIBMSVCRT__"); + + c_file->args.append("-I"); + c_file->args.append(path_from_libc(parent, "mingw" OS_SEP "include" OS_SEP)); + + c_file->args.append("-std=gnu99"); + c_file->args.append("-D_CRTBLD"); + c_file->args.append("-D_WIN32_WINNT=0x0f00"); + c_file->args.append("-D__MSVCRT_VERSION__=0x700"); + + c_file->args.append("-isystem"); + c_file->args.append(path_from_libc(parent, "include" OS_SEP "any-windows-any")); + + c_file->args.append("-g"); + c_file->args.append("-O2"); + + child_gen->c_source_files.append(c_file); +} static const char *get_libc_crt_file(CodeGen *parent, const char *file) { if (parent->libc == nullptr && parent->zig_target->os == OsWindows) { @@ -651,6 +741,24 @@ static const char *get_libc_crt_file(CodeGen *parent, const char *file) { } codegen_build_and_link(child_gen); return buf_ptr(&child_gen->output_file_path); + } else if (strcmp(file, "msvcrt-os.lib") == 0) { + CodeGen *child_gen = create_child_codegen(parent, nullptr, OutTypeLib, nullptr); + codegen_set_out_name(child_gen, buf_create_from_str("msvcrt-os")); + + for (size_t i = 0; i < array_length(msvcrt_common_src); i += 1) { + add_msvcrt_os_dep(parent, child_gen, msvcrt_common_src[i]); + } + if (parent->zig_target->arch == ZigLLVM_x86) { + for (size_t i = 0; i < array_length(msvcrt_i386_src); i += 1) { + add_msvcrt_os_dep(parent, child_gen, msvcrt_i386_src[i]); + } + } else { + for (size_t i = 0; i < array_length(msvcrt_other_src); i += 1) { + add_msvcrt_os_dep(parent, child_gen, msvcrt_other_src[i]); + } + } + codegen_build_and_link(child_gen); + return buf_ptr(&child_gen->output_file_path); } else { zig_unreachable(); } @@ -853,6 +961,7 @@ static Buf *build_a_raw(CodeGen *parent_gen, const char *aname, Buf *full_path, } child_gen->function_sections = true; + child_gen->want_stack_check = WantStackCheckDisabled; codegen_build_and_link(child_gen); return &child_gen->output_file_path; @@ -1446,7 +1555,9 @@ static void add_mingw_link_args(LinkJob *lj, bool is_library) { } lj->args.append(get_libc_crt_file(g, "mingw32.lib")); + lj->args.append(get_libc_crt_file(g, "msvcrt-os.lib")); lj->args.append(get_def_lib(g, "msvcrt", "mingw" OS_SEP "lib-common" OS_SEP "msvcrt.def.in")); + lj->args.append(get_def_lib(g, "kernel32", "mingw" OS_SEP "lib-common" OS_SEP "kernel32.def.in")); } else { if (is_dll) { lj->args.append(get_libc_file(g->libc, "dllcrt2.o")); diff --git a/std/special/compiler_rt.zig b/std/special/compiler_rt.zig index 914f9dcb00..5064e9db29 100644 --- a/std/special/compiler_rt.zig +++ b/std/special/compiler_rt.zig @@ -1,6 +1,12 @@ const builtin = @import("builtin"); const is_test = builtin.is_test; +const is_gnu = switch (builtin.abi) { + .gnu, .gnuabin32, .gnuabi64, .gnueabi, .gnueabihf, .gnux32 => true, + else => false, +}; +const is_mingw = builtin.os == .windows and is_gnu; + comptime { const linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Weak; const strong_linkage = if (is_test) builtin.GlobalLinkage.Internal else builtin.GlobalLinkage.Strong; @@ -231,6 +237,10 @@ comptime { @export("___chkstk", @import("compiler_rt/stack_probe.zig").___chkstk, strong_linkage); @export("__chkstk_ms", @import("compiler_rt/stack_probe.zig").__chkstk_ms, strong_linkage); @export("___chkstk_ms", @import("compiler_rt/stack_probe.zig").___chkstk_ms, strong_linkage); + } else if (is_mingw) { + @export("___chkstk_ms", @import("compiler_rt/stack_probe.zig").___chkstk_ms, strong_linkage); + @export("__stack_chk_fail", __stack_chk_fail, strong_linkage); + @export("__stack_chk_guard", __stack_chk_guard, strong_linkage); } switch (builtin.arch) { @@ -279,6 +289,17 @@ pub fn panic(msg: []const u8, error_return_trace: ?*builtin.StackTrace) noreturn } } +extern fn __stack_chk_fail() noreturn { + @panic("stack smashing detected"); +} + +extern var __stack_chk_guard: usize = blk: { + var buf = [1]u8{0} ** @sizeOf(usize); + buf[@sizeOf(usize) - 1] = 255; + buf[@sizeOf(usize) - 2] = '\n'; + break :blk @bitCast(usize, buf); +}; + extern fn __aeabi_unwind_cpp_pr0() void { unreachable; } -- cgit v1.2.3 From 9c39d5720f4d06bf3e4f14ec50d702b50c9f0cdd Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Sat, 13 Jul 2019 18:38:52 -0400 Subject: ir: add an assertion in phi analysis --- src/ir.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/ir.cpp') diff --git a/src/ir.cpp b/src/ir.cpp index 616bb23132..5193a63ec4 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -17129,6 +17129,7 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh for (size_t i = 0; i < new_incoming_values.length; i += 1) { IrInstruction *new_value = new_incoming_values.at(i); IrBasicBlock *predecessor = new_incoming_blocks.at(i); + ir_assert(predecessor->instruction_list.length != 0, &phi_instruction->base); IrInstruction *branch_instruction = predecessor->instruction_list.pop(); ir_set_cursor_at_end(&ira->new_irb, predecessor); IrInstruction *casted_value = ir_implicit_cast(ira, new_value, resolved_type); -- cgit v1.2.3