From 3b49b877848187460eef193bd044991c71e8c8ce Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Sat, 11 Feb 2023 11:16:31 +0100 Subject: [PATCH] Fix for nolibc (eg wasm). Add multi global declarations. Simplicity wasm export / import. Prevent "extern" functions to have a function body. --- lib/std/core/floatparse.c3 | 9 ++-- lib/std/libc/libc.c3 | 11 +++-- src/compiler/ast.c | 3 ++ src/compiler/compiler_internal.h | 2 +- src/compiler/context.c | 2 + src/compiler/copying.c | 1 + src/compiler/enums.h | 3 +- src/compiler/llvm_codegen.c | 13 +++--- src/compiler/parse_global.c | 50 +++++++++++++++++----- src/compiler/parser.c | 2 +- src/compiler/parser_internal.h | 12 ++++++ src/compiler/sema_decls.c | 12 ++++-- src/compiler/sema_expr.c | 1 + src/compiler/sema_passes.c | 5 +++ src/compiler/sema_types.c | 1 + src/compiler/semantic_analyser.c | 1 + src/version.h | 2 +- test/test_suite/abi/vec2_aarch64.c3t | 13 +++--- test/test_suite/abi/vec2_wasm.c3t | 13 +++--- test/test_suite/abi/vec2_x64.c3t | 12 +++--- test/test_suite/abi/wasm_extern.c3t | 17 ++++++++ test/test_suite/globals/global_no_init.c3t | 19 +++++--- 22 files changed, 146 insertions(+), 58 deletions(-) create mode 100644 test/test_suite/abi/wasm_extern.c3t diff --git a/lib/std/core/floatparse.c3 b/lib/std/core/floatparse.c3 index 62f6f6364..51866de67 100644 --- a/lib/std/core/floatparse.c3 +++ b/lib/std/core/floatparse.c3 @@ -41,12 +41,13 @@ macro double! decfloat(char[] chars, int $bits, int $emin, int sign) int emax = - $emin - $bits + 3; const int[*] P10S = { 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000 }; - usz index = 0; + usz index; bool got_digit = chars[0] == '0'; bool got_rad; + long lrp, dc; + int k, j, lnz; usz len = chars.len; usz last_char = len - 1; - long lrp = 0; assert(len); @@ -77,10 +78,6 @@ macro double! decfloat(char[] chars, int $bits, int $emin, int sign) } } - long dc = 0; - int k; - int j; - int lnz; while (c - '0' < 10u || c == '.') { switch diff --git a/lib/std/libc/libc.c3 b/lib/std/libc/libc.c3 index 09e563793..17a165444 100644 --- a/lib/std/libc/libc.c3 +++ b/lib/std/libc/libc.c3 @@ -250,11 +250,16 @@ fn int fseek(CFile stream, SeekIndex offset, int whence) @weak @extern("fseek") { unreachable("'fseek' not available."); } -fn CFile fopen(char* filename, char* mode) @weak @extern("fopen") +fn CFile fopen(ZString filename, ZString mode) @weak @extern("fopen") { unreachable("'fopen' not available."); } +fn CFile freopen(ZString filename, ZString mode, CFile stream) @weak @extern("fopen") +{ + unreachable("'freopen' not available."); +} + fn usz fwrite(void* ptr, usz size, usz nmemb, CFile stream) @weak @extern("fwrite") { unreachable("'fwrite' not available."); @@ -280,7 +285,7 @@ fn int fputc(int c, CFile stream) @weak @extern("fputc") unreachable("'fputc' not available."); } -fn char* fgets(char* str, int n, CFile stream) @weak @extern("fgets") +fn char* fgets(ZString str, int n, CFile stream) @weak @extern("fgets") { unreachable("'fgets' not available."); } @@ -303,7 +308,7 @@ fn int putchar(int c) @weak @extern("putchar") { unreachable("'putchar' not available."); } -fn int puts(char* str) @weak @extern("puts") +fn int puts(ZString str) @weak @extern("puts") { unreachable("'puts' not available."); } diff --git a/src/compiler/ast.c b/src/compiler/ast.c index ee777f4f3..abca52fb6 100644 --- a/src/compiler/ast.c +++ b/src/compiler/ast.c @@ -98,6 +98,7 @@ Decl *decl_new_with_type(const char *name, SourceSpan loc, DeclKind decl_type, V case DECL_FINALIZE: case DECL_CT_ECHO: case DECL_CT_INCLUDE: + case DECL_GLOBALS: UNREACHABLE } Type *type = type_new(kind, name ? name : "$anon"); @@ -175,6 +176,8 @@ const char *decl_to_a_name(Decl *decl) return "a static finalizer"; case DECL_CT_INCLUDE: return "an include"; + case DECL_GLOBALS: + return "globals"; case DECL_VAR: switch (decl->var.kind) { diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index 38fc8b956..38f27a996 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -674,7 +674,6 @@ typedef struct Decl_ bool obfuscate : 1; bool is_dynamic : 1; bool is_synthetic : 1; - bool is_wasm_interface : 1; bool is_export : 1; OperatorOverload operator : 4; union @@ -727,6 +726,7 @@ typedef struct Decl_ EnumConstantDecl enum_constant; FuncDecl func_decl; AttrDecl attr_decl; + Decl** decls; TypedefDecl typedef_decl; DefineDecl define_decl; CtIfDecl ct_if_decl; diff --git a/src/compiler/context.c b/src/compiler/context.c index 90895e144..44f3e06f6 100644 --- a/src/compiler/context.c +++ b/src/compiler/context.c @@ -149,6 +149,7 @@ void decl_register(Decl *decl) case DECL_DECLARRAY: case DECL_BODYPARAM: case DECL_CT_INCLUDE: + case DECL_GLOBALS: UNREACHABLE case DECL_ATTRIBUTE: case DECL_BITSTRUCT: @@ -260,6 +261,7 @@ void unit_register_global_decl(CompilationUnit *unit, Decl *decl) case DECL_CT_CASE: case DECL_DECLARRAY: case DECL_BODYPARAM: + case DECL_GLOBALS: UNREACHABLE case DECL_CT_IF: case DECL_CT_SWITCH: diff --git a/src/compiler/copying.c b/src/compiler/copying.c index f5386679a..302014de1 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -850,6 +850,7 @@ Decl *copy_decl(CopyStruct *c, Decl *decl) MACRO_COPY_DECL_LIST(copy->methods); break; case DECL_DECLARRAY: + case DECL_GLOBALS: UNREACHABLE case DECL_BITSTRUCT: copy_decl_type(copy); diff --git a/src/compiler/enums.h b/src/compiler/enums.h index 9fef9c09c..f4547dce8 100644 --- a/src/compiler/enums.h +++ b/src/compiler/enums.h @@ -143,6 +143,7 @@ typedef enum DECL_FAULT, DECL_FAULTVALUE, DECL_FUNC, + DECL_GLOBALS, DECL_INITIALIZE, DECL_FINALIZE, DECL_GENERIC, @@ -162,7 +163,7 @@ typedef enum case DECL_DECLARRAY: case DECL_CT_IF: case DECL_CT_ELSE: case DECL_CT_ELIF: \ case DECL_CT_SWITCH: case DECL_CT_CASE: case DECL_ATTRIBUTE: case DECL_LABEL: \ case DECL_DEFINE: case DECL_CT_ASSERT: case DECL_GENERIC: case DECL_INITIALIZE: \ - case DECL_FINALIZE: case DECL_CT_ECHO: case DECL_CT_INCLUDE + case DECL_FINALIZE: case DECL_CT_ECHO: case DECL_CT_INCLUDE: case DECL_GLOBALS #define NON_RUNTIME_EXPR EXPR_DESIGNATOR: case EXPR_POISONED: \ case EXPR_TYPEINFO: case EXPR_CT_IDENT: case EXPR_HASH_IDENT: \ diff --git a/src/compiler/llvm_codegen.c b/src/compiler/llvm_codegen.c index 2af10472d..14ccc81c3 100644 --- a/src/compiler/llvm_codegen.c +++ b/src/compiler/llvm_codegen.c @@ -1021,17 +1021,17 @@ void llvm_append_function_attributes(GenContext *c, Decl *decl) { llvm_attribute_add(c, function, attribute_id.noreturn, -1); } - if (decl->is_wasm_interface && arch_is_wasm(platform_target.arch)) + if (decl->is_export && arch_is_wasm(platform_target.arch)) { - if (decl->visibility == VISIBLE_EXTERN) - { - llvm_attribute_add_string(c, function, "wasm-import-name", decl_get_extname(decl), -1); - } - else if (c->code_module == decl->unit->module) + if (c->code_module == decl->unit->module) { llvm_attribute_add_string(c, function, "wasm-export-name", decl_get_extname(decl), -1); } } + if (decl->visibility == VISIBLE_EXTERN && arch_is_wasm(platform_target.arch)) + { + llvm_attribute_add_string(c, function, "wasm-import-name", decl_get_extname(decl), -1); + } if (decl->alignment != type_abi_alignment(decl->type)) { llvm_set_alignment(function, decl->alignment); @@ -1104,6 +1104,7 @@ LLVMValueRef llvm_get_ref(GenContext *c, Decl *decl) case DECL_BODYPARAM: case DECL_CT_ECHO: case DECL_CT_INCLUDE: + case DECL_GLOBALS: UNREACHABLE; } UNREACHABLE diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index de5a45630..cd4761266 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -96,7 +96,7 @@ static inline bool parse_top_level_block(ParseContext *c, Decl ***decls, TokenTy assert(decl); if (decl_ok(decl)) { - vec_add(*decls, decl); + add_decl_to_list(decls, decl); } else { @@ -175,7 +175,7 @@ static inline Decl *parse_ct_case(ParseContext *c) TokenType type = c->tok; if (type == TOKEN_CT_DEFAULT || type == TOKEN_CT_CASE || type == TOKEN_CT_ENDSWITCH) break; ASSIGN_DECL_OR_RET(Decl *stmt, parse_top_level_statement(c, NULL), poisoned_decl); - vec_add(decl->ct_case_decl.body, stmt); + add_decl_to_list(&decl->ct_case_decl.body, stmt); } return decl; } @@ -1062,9 +1062,6 @@ static inline Decl *parse_global_declaration(ParseContext *c, Visibility visibil ASSIGN_TYPE_OR_RET(TypeInfo *type, parse_optional_type(c), poisoned_decl); - Decl *decl = DECL_VAR_NEW(type, VARDECL_GLOBAL, visibility); - - decl->var.is_threadlocal = threadlocal; if (tok_is(c, TOKEN_CONST_IDENT)) { @@ -1072,23 +1069,54 @@ static inline Decl *parse_global_declaration(ParseContext *c, Visibility visibil return poisoned_decl; } - if (!try_consume(c, TOKEN_IDENT)) + Decl *decl; + Decl **decls = NULL; + while (true) { - if (token_is_some_ident(c->tok)) + decl = DECL_VAR_NEW(type, VARDECL_GLOBAL, visibility); + decl->var.is_threadlocal = threadlocal; + if (!try_consume(c, TOKEN_IDENT)) { - SEMA_ERROR_HERE("I expected a variable name here, but global variables need to start with lower case."); + if (token_is_some_ident(c->tok)) + { + SEMA_ERROR_HERE("I expected a variable name here, but global variables need to start with lower case."); + return poisoned_decl; + } + SEMA_ERROR_HERE("The name of a global variable was expected here"); return poisoned_decl; } - SEMA_ERROR_HERE("The name of a global variable was expected here"); - return poisoned_decl; + if (!try_consume(c, TOKEN_COMMA)) break; + vec_add(decls, decl); } + // Add the last, or we miss it. + if (decls) vec_add(decls, decl); if (!parse_attributes(c, &decl->attributes)) return poisoned_decl; if (try_consume(c, TOKEN_EQ)) { + if (decls) + { + SEMA_ERROR_HERE("Initialization is not allowed with multiple declarations."); + return poisoned_decl; + } if (!parse_decl_initializer(c, decl, true)) return poisoned_decl; } CONSUME_EOS_OR_RET(poisoned_decl); + Attr **attributes = decl->attributes; + if (attributes) + { + FOREACH_BEGIN(Decl *d, decls) + if (d == decl) continue; + d->attributes = copy_attributes_single(attributes); + FOREACH_END(); + } + if (decls) + { + decl = decl_calloc(); + decl->decl_kind = DECL_GLOBALS; + decl->decls = decls; + return decl; + } return decl; } @@ -2606,7 +2634,7 @@ static Decl *parse_include(ParseContext *c) decl_poison(decl); goto END; } - vec_add(list, inner); + add_decl_to_list(&list, inner); } decl->include.decls = list; END: diff --git a/src/compiler/parser.c b/src/compiler/parser.c index cdf1f2f44..cbfb9664a 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -73,7 +73,7 @@ static inline void parse_translation_unit(ParseContext *c) if (!decl) continue; if (decl_ok(decl)) { - vec_add(c->unit->global_decls, decl); + add_decl_to_list(&c->unit->global_decls, decl); } else { diff --git a/src/compiler/parser_internal.h b/src/compiler/parser_internal.h index f479438e3..ddc21fe50 100644 --- a/src/compiler/parser_internal.h +++ b/src/compiler/parser_internal.h @@ -62,6 +62,18 @@ bool parse_parameters(ParseContext *c, Visibility visibility, Decl ***params_ref bool parse_arg_list(ParseContext *c, Expr ***result, TokenType param_end, bool *splat, bool vasplat); Expr *parse_type_compound_literal_expr_after_type(ParseContext *c, TypeInfo *type_info); +INLINE void add_decl_to_list(Decl ***list, Decl *decl) +{ + if (decl->decl_kind == DECL_GLOBALS) + { + FOREACH_BEGIN(Decl *d, decl->decls) + vec_add(*list, d); + FOREACH_END(); + return; + } + vec_add(*list, decl); +} + bool parse_module(ParseContext *c, AstId docs); Expr *parse_generic_parameter(ParseContext *c); bool try_consume(ParseContext *c, TokenType type); diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 49288fafb..c130533ce 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -1656,7 +1656,7 @@ static bool sema_analyse_attribute(SemaContext *context, Decl *decl, Attr *attr, decl->is_weak = true; break; case ATTRIBUTE_WASM: - decl->is_wasm_interface = true; + decl->is_export = true; break; case ATTRIBUTE_NAKED: assert(domain == ATTR_FUNC); @@ -1969,7 +1969,10 @@ static inline MainType sema_find_main_type(SemaContext *context, Signature *sig, static inline Decl *sema_create_synthetic_main(SemaContext *context, Decl *decl, MainType main, bool int_return, bool err_return, bool is_winmain, bool is_wmain) { - Decl *function = decl_new(DECL_FUNC, NULL, decl->span, VISIBLE_EXTERN); + Decl *function = decl_new(DECL_FUNC, NULL, decl->span, VISIBLE_PUBLIC); + function->is_export = true; + function->has_extname = true; + function->extname = kw_mainstub; function->name = kw_mainstub; function->unit = decl->unit; @@ -2158,7 +2161,9 @@ static inline bool sema_analyse_main_function(SemaContext *context, Decl *decl) if ((type == MAIN_TYPE_RAW || type == MAIN_TYPE_NO_ARGS) && is_int_return && !is_winmain) { // Int return is pass-through at the moment. - decl->visibility = VISIBLE_EXTERN; + decl->is_export = true; + decl->has_extname = true; + decl->extname = kw_main; function = decl; goto REGISTER_MAIN; } @@ -3052,6 +3057,7 @@ bool sema_analyse_decl(SemaContext *context, Decl *decl) case DECL_DECLARRAY: case DECL_BODYPARAM: case DECL_CT_INCLUDE: + case DECL_GLOBALS: UNREACHABLE } decl->resolve_status = RESOLVE_DONE; diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 3d5248cc6..80badeee0 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -549,6 +549,7 @@ static inline bool sema_cast_ident_rvalue(SemaContext *context, Expr *expr) case DECL_INITIALIZE: case DECL_FINALIZE: case DECL_CT_INCLUDE: + case DECL_GLOBALS: UNREACHABLE case DECL_POISONED: return expr_poison(expr); diff --git a/src/compiler/sema_passes.c b/src/compiler/sema_passes.c index e0d6ff5a7..bd99815b7 100644 --- a/src/compiler/sema_passes.c +++ b/src/compiler/sema_passes.c @@ -368,6 +368,11 @@ void sema_analysis_pass_ct_echo(Module *module) static inline bool analyse_func_body(SemaContext *context, Decl *decl) { if (!decl->func_decl.body) return true; + if (decl->visibility == VISIBLE_EXTERN) + { + SEMA_ERROR(decl, "'extern' functions should never have a body."); + return decl_poison(decl); + } // Don't analyse functions that are tests. if (decl->func_decl.attr_test && !active_target.testing) return true; if (!sema_analyse_function_body(context, decl)) return decl_poison(decl); diff --git a/src/compiler/sema_types.c b/src/compiler/sema_types.c index 86d60e781..464a74531 100644 --- a/src/compiler/sema_types.c +++ b/src/compiler/sema_types.c @@ -245,6 +245,7 @@ static bool sema_resolve_type_identifier(SemaContext *context, TypeInfo *type_in case DECL_DECLARRAY: case DECL_BODYPARAM: case DECL_CT_INCLUDE: + case DECL_GLOBALS: UNREACHABLE } UNREACHABLE diff --git a/src/compiler/semantic_analyser.c b/src/compiler/semantic_analyser.c index 56d68c860..77cff493d 100644 --- a/src/compiler/semantic_analyser.c +++ b/src/compiler/semantic_analyser.c @@ -181,6 +181,7 @@ static void register_generic_decls(CompilationUnit *unit, Decl **decls) case DECL_CT_ELSE: case DECL_BODYPARAM: case DECL_CT_INCLUDE: + case DECL_GLOBALS: UNREACHABLE case DECL_MACRO: case DECL_DEFINE: diff --git a/src/version.h b/src/version.h index f5e16775d..cfc5794f1 100644 --- a/src/version.h +++ b/src/version.h @@ -1 +1 @@ -#define COMPILER_VERSION "0.4.58" \ No newline at end of file +#define COMPILER_VERSION "0.4.59" \ No newline at end of file diff --git a/test/test_suite/abi/vec2_aarch64.c3t b/test/test_suite/abi/vec2_aarch64.c3t index df230db68..3e98933f6 100644 --- a/test/test_suite/abi/vec2_aarch64.c3t +++ b/test/test_suite/abi/vec2_aarch64.c3t @@ -5,12 +5,13 @@ struct Vector2 { float x; float y; } -extern fn Vector2 vector2_zero() { return Vector2 {}; } -extern fn Vector2 vector2_one() { return Vector2 {}; } -extern fn Vector2 vector2_add(Vector2 v1, Vector2 v2) { return Vector2 {}; } -extern fn Vector2 vector2_add_value(Vector2 v, float add) { return Vector2 {}; } -extern fn Vector2 vector2_subtract(Vector2 v1, Vector2 v2) { return Vector2 {}; } -extern fn Vector2 vector2_subtract_value(Vector2 v, float sub) { return Vector2 {}; } +fn Vector2 vector2_zero() @extern("vector2_zero") { return Vector2 {}; } +fn Vector2 vector2_one() @extern("vector2_one") { return Vector2 {}; } +fn Vector2 vector2_add(Vector2 v1, Vector2 v2) @extern("vector2_add") { return Vector2 {}; } +fn Vector2 vector2_add_value(Vector2 v, float add) @extern("vector2_add_value") { return Vector2 {}; } +fn Vector2 vector2_subtract(Vector2 v1, Vector2 v2) @extern("vector2_subtract") { return Vector2 {}; } +fn Vector2 vector2_subtract_value(Vector2 v, float sub) @extern("vector2_subtract_value") { return Vector2 {}; } + /* #expect: abi.ll diff --git a/test/test_suite/abi/vec2_wasm.c3t b/test/test_suite/abi/vec2_wasm.c3t index 783bd350b..4e77717f9 100644 --- a/test/test_suite/abi/vec2_wasm.c3t +++ b/test/test_suite/abi/vec2_wasm.c3t @@ -5,12 +5,12 @@ struct Vector2 { float x; float y; } -extern fn Vector2 vector2_zero() { return Vector2 {}; } -extern fn Vector2 vector2_one() { return Vector2 {}; } -extern fn Vector2 vector2_add(Vector2 v1, Vector2 v2) { return Vector2 {}; } -extern fn Vector2 vector2_add_value(Vector2 v, float add) { return Vector2 {}; } -extern fn Vector2 vector2_subtract(Vector2 v1, Vector2 v2) { return Vector2 {}; } -extern fn Vector2 vector2_subtract_value(Vector2 v, float sub) { return Vector2 {}; } +fn Vector2 vector2_zero() @extern("vector2_zero") { return Vector2 {}; } +fn Vector2 vector2_one() @extern("vector2_one") { return Vector2 {}; } +fn Vector2 vector2_add(Vector2 v1, Vector2 v2) @extern("vector2_add") { return Vector2 {}; } +fn Vector2 vector2_add_value(Vector2 v, float add) @extern("vector2_add_value") { return Vector2 {}; } +fn Vector2 vector2_subtract(Vector2 v1, Vector2 v2) @extern("vector2_subtract") { return Vector2 {}; } +fn Vector2 vector2_subtract_value(Vector2 v, float sub) @extern("vector2_subtract_value") { return Vector2 {}; } /* #expect: abi.ll @@ -73,7 +73,6 @@ entry: ret void } -; Function Attrs: nounwind define void @vector2_subtract_value(ptr noalias sret(%Vector2) align 4 %0, ptr byval(%Vector2) align 4 %1, float %2) #0 { entry: %literal = alloca %Vector2, align 4 diff --git a/test/test_suite/abi/vec2_x64.c3t b/test/test_suite/abi/vec2_x64.c3t index 00c2e1129..c1edebe4a 100644 --- a/test/test_suite/abi/vec2_x64.c3t +++ b/test/test_suite/abi/vec2_x64.c3t @@ -5,12 +5,12 @@ struct Vector2 { float x; float y; } -extern fn Vector2 vector2_zero() { return Vector2 {}; } -extern fn Vector2 vector2_one() { return Vector2 {}; } -extern fn Vector2 vector2_add(Vector2 v1, Vector2 v2) { return Vector2 {}; } -extern fn Vector2 vector2_add_value(Vector2 v, float add) { return Vector2 {}; } -extern fn Vector2 vector2_subtract(Vector2 v1, Vector2 v2) { return Vector2 {}; } -extern fn Vector2 vector2_subtract_value(Vector2 v, float sub) { return Vector2 {}; } +fn Vector2 vector2_zero() @extern("vector2_zero") { return Vector2 {}; } +fn Vector2 vector2_one() @extern("vector2_one") { return Vector2 {}; } +fn Vector2 vector2_add(Vector2 v1, Vector2 v2) @extern("vector2_add") { return Vector2 {}; } +fn Vector2 vector2_add_value(Vector2 v, float add) @extern("vector2_add_value") { return Vector2 {}; } +fn Vector2 vector2_subtract(Vector2 v1, Vector2 v2) @extern("vector2_subtract") { return Vector2 {}; } +fn Vector2 vector2_subtract_value(Vector2 v, float sub) @extern("vector2_subtract_value") { return Vector2 {}; } /* #expect: abi.ll diff --git a/test/test_suite/abi/wasm_extern.c3t b/test/test_suite/abi/wasm_extern.c3t new file mode 100644 index 000000000..51e32740a --- /dev/null +++ b/test/test_suite/abi/wasm_extern.c3t @@ -0,0 +1,17 @@ +// #target: wasm32 +module test; +extern fn int get_abc(); +fn int hello() @export("fgh") +{ + return 1; +} + +/* #expect: test.ll + +target triple = "wasm32-unknown-unknown" + +declare i32 @get_abc() #0 +define i32 @fgh() #1 + +attributes #0 = { nounwind "wasm-import-name"="get_abc" } +attributes #1 = { nounwind "wasm-export-name"="fgh" } diff --git a/test/test_suite/globals/global_no_init.c3t b/test/test_suite/globals/global_no_init.c3t index 8aecf5298..67d82b768 100644 --- a/test/test_suite/globals/global_no_init.c3t +++ b/test/test_suite/globals/global_no_init.c3t @@ -7,6 +7,10 @@ struct Abc int z @noinit; Abc y @noinit; +int a, b, c; +int x1, y1 @noinit; +tlocal int w, v; + fn void main() { z = y.x[0]; @@ -16,10 +20,13 @@ fn void main() @test_z = local_unnamed_addr global i32 undef, align 4 @test_y = local_unnamed_addr global %Abc undef, align 4 +@test_a = local_unnamed_addr global i32 0, align 4 +@test_b = local_unnamed_addr global i32 0, align 4 +@test_c = local_unnamed_addr global i32 0, align 4 +@test_x1 = local_unnamed_addr global i32 undef, align 4 +@test_y1 = local_unnamed_addr global i32 undef, align 4 +@test_w = thread_local local_unnamed_addr global i32 0, align 4 +@test_v = thread_local local_unnamed_addr global i32 0, align 4 -define void @test_main() #0 { -entry: - %0 = load i32, ptr @test_y, align 4 - store i32 %0, ptr @test_z, align 4 - ret void -} \ No newline at end of file +%0 = load i32, ptr @test_y, align 4 +store i32 %0, ptr @test_z, align 4