From: Francis De Brabandere <francisdb@gmail.com> Reject duplicate Sub/Function declarations inside a class, and any Sub or Function declared with the same name as an existing class member (Dim, Property, another Sub/Function), returning error 1041. Report the error at the location of the second declaration using the tracked name_loc, so the position matches Windows behavior. --- dlls/vbscript/compile.c | 8 +++++ dlls/vbscript/parser.y | 7 +++- dlls/vbscript/tests/run.c | 75 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 89 insertions(+), 1 deletion(-) diff --git a/dlls/vbscript/compile.c b/dlls/vbscript/compile.c index 28268af5342..16e661c98ff 100644 --- a/dlls/vbscript/compile.c +++ b/dlls/vbscript/compile.c @@ -2043,6 +2043,14 @@ static HRESULT compile_class(compile_ctx_t *ctx, class_decl_t *class_decl) for(prop_decl = class_decl->props, i=0; prop_decl; prop_decl = prop_decl->next, i++) { if(lookup_class_funcs(class_desc, prop_decl->name)) { + function_decl_t *func_iter; + unsigned loc = prop_decl->loc; + for(func_iter = class_decl->funcs; func_iter; func_iter = func_iter->next) { + if(!vbs_wcsicmp(func_iter->name, prop_decl->name) && func_iter->name_loc > loc) + loc = func_iter->name_loc; + } + WARN("%s: redefined\n", debugstr_w(prop_decl->name)); + ctx->loc = loc; return MAKE_VBSERROR(VBSE_NAME_REDEFINED); } diff --git a/dlls/vbscript/parser.y b/dlls/vbscript/parser.y index 3e1cd5b76c3..484df3da770 100644 --- a/dlls/vbscript/parser.y +++ b/dlls/vbscript/parser.y @@ -1233,13 +1233,18 @@ static class_decl_t *add_class_function(parser_ctx_t *ctx, class_decl_t *class_d return NULL; } if(!wcsicmp(iter->name, decl->name)) { - if(decl->type == FUNC_SUB || decl->type == FUNC_FUNCTION) { + if(decl->type == FUNC_SUB || decl->type == FUNC_FUNCTION + || iter->type == FUNC_SUB || iter->type == FUNC_FUNCTION) { + WARN("%s::%s redefined\n", debugstr_w(class_decl->name), debugstr_w(decl->name)); + ctx->error_loc = iter->name_loc; ctx->hres = MAKE_VBSERROR(VBSE_NAME_REDEFINED); return NULL; } while(1) { if(iter->type == decl->type) { + WARN("%s::%s redefined\n", debugstr_w(class_decl->name), debugstr_w(decl->name)); + ctx->error_loc = iter->name_loc; ctx->hres = MAKE_VBSERROR(VBSE_NAME_REDEFINED); return NULL; } diff --git a/dlls/vbscript/tests/run.c b/dlls/vbscript/tests/run.c index 9a86a3e15a6..d7dd871a30c 100644 --- a/dlls/vbscript/tests/run.c +++ b/dlls/vbscript/tests/run.c @@ -3349,6 +3349,81 @@ static void test_parse_errors(void) "End Class\n", 2, 6, L"Class M", S_OK, 1041 + }, + { + /* Duplicate Sub inside Class */ + L"Class N\n" + " Sub Foo\n" + " End Sub\n" + " Sub Foo\n" + " End Sub\n" + "End Class\n", + 3, 8, + L" Sub Foo", S_OK, 1041 + }, + { + /* Duplicate Function inside Class */ + L"Class O\n" + " Function Foo\n" + " End Function\n" + " Function Foo\n" + " End Function\n" + "End Class\n", + 3, 13, + L" Function Foo", S_OK, 1041 + }, + { + /* Sub and Function with same name inside Class */ + L"Class P\n" + " Sub Foo\n" + " End Sub\n" + " Function Foo\n" + " End Function\n" + "End Class\n", + 3, 13, + L" Function Foo", S_OK, 1041 + }, + { + /* Property Get and Sub with same name inside Class */ + L"Class Q\n" + " Property Get Foo\n" + " End Property\n" + " Sub Foo\n" + " End Sub\n" + "End Class\n", + 3, 8, + L" Sub Foo", S_OK, 1041 + }, + { + /* Duplicate Property Get inside Class */ + L"Class R\n" + " Property Get Foo\n" + " End Property\n" + " Property Get Foo\n" + " End Property\n" + "End Class\n", + 3, 17, + L" Property Get Foo", S_OK, 1041 + }, + { + /* Dim and Sub with same name inside Class */ + L"Class S\n" + " Dim Foo\n" + " Sub Foo\n" + " End Sub\n" + "End Class\n", + 2, 8, + L" Sub Foo", S_OK, 1041 + }, + { + /* Sub and Dim with same name inside Class */ + L"Class T\n" + " Sub Foo\n" + " End Sub\n" + " Dim Foo\n" + "End Class\n", + 3, 8, + L" Dim Foo", S_OK, 1041 } }; HRESULT hres; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10464