Skip to content

Commit

Permalink
Using winmain would call the wrong definition #1265.
Browse files Browse the repository at this point in the history
  • Loading branch information
lerno committed Jul 29, 2024
1 parent 08c7b35 commit e66001c
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 43 deletions.
24 changes: 12 additions & 12 deletions lib/std/core/private/main_stub.c3
Original file line number Diff line number Diff line change
Expand Up @@ -84,61 +84,61 @@ macro void release_wargs(String[] list) @private
free(list.ptr);
}

macro int @win_to_err_main_noargs(#m, void* handle, Char16* cmd_line, int show_cmd)
macro int @win_to_err_main_noargs(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd)
{
if (catch #m()) return 1;
return 0;
}
macro int @win_to_int_main_noargs(#m, void* handle, Char16* cmd_line, int show_cmd) => #m();
macro int @win_to_void_main_noargs(#m, void* handle, Char16* cmd_line, int show_cmd)
macro int @win_to_int_main_noargs(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd) => #m();
macro int @win_to_void_main_noargs(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd)
{
#m();
return 0;
}

macro int @win_to_err_main_args(#m, void* handle, Char16* cmd_line, int show_cmd)
macro int @win_to_err_main_args(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd)
{
String[] args = win_command_line_to_strings(cmd_line);
defer release_wargs(args);
if (catch #m(args)) return 1;
return 0;
}

macro int @win_to_int_main_args(#m, void* handle, Char16* cmd_line, int show_cmd)
macro int @win_to_int_main_args(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd)
{
String[] args = win_command_line_to_strings(cmd_line);
defer release_wargs(args);
return #m(args);
}

macro int @win_to_void_main_args(#m, void* handle, Char16* cmd_line, int show_cmd)
macro int @win_to_void_main_args(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd)
{
String[] args = win_command_line_to_strings(cmd_line);
defer release_wargs(args);
#m(args);
return 0;
}

macro int @win_to_err_main(#m, void* handle, Char16* cmd_line, int show_cmd)
macro int @win_to_err_main(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd)
{
String[] args = win_command_line_to_strings(cmd_line);
defer release_wargs(args);
if (catch #m(handle, args, show_cmd)) return 1;
if (catch #m(handle, prev_handle, args, show_cmd)) return 1;
return 0;
}

macro int @win_to_int_main(#m, void* handle, Char16* cmd_line, int show_cmd)
macro int @win_to_int_main(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd)
{
String[] args = win_command_line_to_strings(cmd_line);
defer release_wargs(args);
return #m(handle, args, show_cmd);
return #m(handle, prev_handle, args, show_cmd);
}

macro int @win_to_void_main(#m, void* handle, Char16* cmd_line, int show_cmd)
macro int @win_to_void_main(#m, void* handle, void* prev_handle, Char16* cmd_line, int show_cmd)
{
String[] args = win_command_line_to_strings(cmd_line);
defer release_wargs(args);
#m(handle, args, show_cmd);
#m(handle, prev_handle, args, show_cmd);
return 0;
}

Expand Down
1 change: 1 addition & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ None
- Unsplat with named parameters was accidentally disallowed.
- Reference parameter doesn't work with vector subscript #1250.
- The msvc_sdk script failed to work properly on windows when run in folders with spaces.
- Using winmain would call the wrong definition #1265.

### Stdlib changes
- Added `remove_first_item` `remove_last_item` and `remove_item` as aliases for the `match` functions.
Expand Down
65 changes: 34 additions & 31 deletions src/compiler/sema_decls.c
Original file line number Diff line number Diff line change
Expand Up @@ -2910,37 +2910,40 @@ static inline MainType sema_find_main_type(SemaContext *context, Signature *sig,
return MAIN_TYPE_ERROR;
}
return MAIN_TYPE_RAW;
case 3:
case 4:
if (!is_win32 || !is_winmain) break;
arg_type = type_flatten(params[0]->type);
arg_type2 = type_flatten(params[1]->type);
if (arg_type != type_voidptr)
for (int i = 0; i < 2; i++)
{
SEMA_ERROR(params[0], "Expected a parameter of type 'void*' (HINSTANCE)");
return MAIN_TYPE_ERROR;
arg_type = type_flatten(params[i]->type);
if (arg_type != type_voidptr)
{
SEMA_ERROR(params[i], "Expected a parameter of type 'void*' (Win32_HINSTANCE)");
return MAIN_TYPE_ERROR;
}
}
arg_type2 = type_flatten(params[2]->type);
if (arg_type2 != type_get_slice(type_string))
{
SEMA_ERROR(params[1], "Expected a parameter of type 'String[]'.");
return MAIN_TYPE_ERROR;
}
if (type_flatten(params[2]->type) != type_cint)
if (type_flatten(params[3]->type) != type_cint)
{
SEMA_ERROR(params[2], "Expected a parameter of type %s for the 'showCmd' parameter.",
SEMA_ERROR(params[3], "Expected a parameter of type %s for the 'showCmd' parameter.",
type_quoted_error_string(type_cint));
return MAIN_TYPE_ERROR;
}
if (!is_win32)
{
SEMA_ERROR(params[0], "'main(HINSTANCE, String[], int) is only valid for Windows.");
SEMA_ERROR(params[0], "'main(Win32_HINSTANCE, Win32_HINSTANCE, String[], int) is only valid for Windows.");
return MAIN_TYPE_ERROR;
}
return MAIN_TYPE_WIN;
default:
break;
}
SEMA_ERROR(params[0], (is_win32 & is_winmain)
? "Expected zero, 1 or 3 parameters for main."
? "Expected zero, 1 or 4 parameters for main."
: "Expected zero or 1 parameters for main.");
return MAIN_TYPE_ERROR;

Expand All @@ -2956,37 +2959,37 @@ static inline Decl *sema_create_synthetic_main(SemaContext *context, Decl *decl,
function->unit = decl->unit;

// Pick wWinMain, main or wmain
Decl *param1;
Decl *param2;
Decl *param3 = NULL;

Decl *params[4] = { NULL, NULL, NULL, NULL };
int param_count;
if (is_winmain)
{
function->extname = kw_winmain;
param1 = decl_new_generated_var(type_voidptr, VARDECL_PARAM, decl->span);
param2 = decl_new_generated_var(type_get_ptr(type_ushort), VARDECL_PARAM, decl->span);
param3 = decl_new_generated_var(type_cint, VARDECL_PARAM, decl->span);
params[0] = decl_new_generated_var(type_voidptr, VARDECL_PARAM, decl->span);
params[1] = decl_new_generated_var(type_voidptr, VARDECL_PARAM, decl->span);
params[2] = decl_new_generated_var(type_get_ptr(type_ushort), VARDECL_PARAM, decl->span);
params[3] = decl_new_generated_var(type_cint, VARDECL_PARAM, decl->span);
param_count = 4;
}
else if (is_wmain)
{
function->extname = kw_wmain;
param1 = decl_new_generated_var(type_cint, VARDECL_PARAM, decl->span);
param2 = decl_new_generated_var(type_get_ptr(type_get_ptr(type_ushort)), VARDECL_PARAM, decl->span);
params[0] = decl_new_generated_var(type_cint, VARDECL_PARAM, decl->span);
params[1] = decl_new_generated_var(type_get_ptr(type_get_ptr(type_ushort)), VARDECL_PARAM, decl->span);
param_count = 2;
}
else
{
function->extname = kw_main;
param1 = decl_new_generated_var(type_cint, VARDECL_PARAM, decl->span);
param2 = decl_new_generated_var(type_get_ptr(type_get_ptr(type_char)), VARDECL_PARAM, decl->span);
params[0] = decl_new_generated_var(type_cint, VARDECL_PARAM, decl->span);
params[1] = decl_new_generated_var(type_get_ptr(type_get_ptr(type_char)), VARDECL_PARAM, decl->span);
param_count = 2;
}

function->has_extname = true;
function->func_decl.signature.rtype = type_infoid(type_info_new_base(type_cint, decl->span));
function->func_decl.signature.vararg_index = is_winmain ? 3 : 2;
function->func_decl.signature.vararg_index = param_count;
Decl **main_params = NULL;
vec_add(main_params, param1);
vec_add(main_params, param2);
if (param3) vec_add(main_params, param3);
for (int i = 0; i < param_count; i++) vec_add(main_params, params[i]);
function->func_decl.signature.params = main_params;
Ast *body = new_ast(AST_COMPOUND_STMT, decl->span);
AstId *next = &body->compound_stmt.first_stmt;
Expand Down Expand Up @@ -3070,13 +3073,13 @@ NEXT:;
Expr *call = expr_new(EXPR_CALL, decl->span);
Expr *fn_ref = expr_variable(decl);
vec_add(call->call_expr.arguments, fn_ref);
vec_add(call->call_expr.arguments, expr_variable(param1));
vec_add(call->call_expr.arguments, expr_variable(param2));
if (param3) vec_add(call->call_expr.arguments, expr_variable(param3));
for (int i = 0; i < param_count; i++)
{
Expr *arg = expr_variable(params[i]);
vec_add(call->call_expr.arguments, arg);
}
call->call_expr.function = exprid(invoker);
param1->resolve_status = RESOLVE_NOT_DONE;
param2->resolve_status = RESOLVE_NOT_DONE;
if (param3) param3->resolve_status = RESOLVE_NOT_DONE;
for (int i = 0; i < param_count; i++) params[i]->resolve_status = RESOLVE_NOT_DONE;
ast_append(&next, ret_stmt);
ret_stmt->return_stmt.expr = call;
function->func_decl.body = astid(body);
Expand Down

0 comments on commit e66001c

Please sign in to comment.