diff --git a/releasenotes.md b/releasenotes.md index d9b5ac277..594681cd4 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -34,6 +34,7 @@ - $typeof(*x) should be valid when x is an `[out]` parameter #1226 - Fix ABI lowering for 128 bit vectors on Linux. - Bad error message when using a generic method without generic parameters #1228 +- Private function called from nested macro not visible to linker #1232 ### Stdlib changes - Added `remove_first_item` `remove_last_item` and `remove_item` as aliases for the `match` functions. @@ -41,6 +42,8 @@ - Remove "panic" text from unreachable() when safe mode is turned off. - Added `@unaligned_store` and `@unaligned_load`. - Null ZString, DString or pointer prints "(null)" for printf. +- Updated sorting API. +- Insertion sort and counting sort added. ## 0.6.0 Change list @@ -107,8 +110,6 @@ - Path normalization - fix possible null terminator out of bounds. - Add 'zstr' variants for `string::new_format` / `string::tformat`. - Fix mutex and wait signatures for Win32. -- Updated sorting API. -- Insertion sort and counting sort added. ## 0.5.5 Change list diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index ed0588c4b..0afb4dfde 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -2193,7 +2193,7 @@ const char *get_exe_extension(void); CompilationUnit * unit_create(File *file); void unit_register_global_decl(CompilationUnit *unit, Decl *decl); -void unit_register_external_symbol(CompilationUnit *unit, Decl *decl); +void unit_register_external_symbol(SemaContext *context, Decl *decl); bool unit_add_import(CompilationUnit *unit, Path *path, bool private_import); bool context_set_module_from_filename(ParseContext *context); diff --git a/src/compiler/context.c b/src/compiler/context.c index 293e32aa6..963a57d8c 100644 --- a/src/compiler/context.c +++ b/src/compiler/context.c @@ -106,9 +106,11 @@ bool context_set_module(ParseContext *context, Path *path, const char **generic_ } -void unit_register_external_symbol(CompilationUnit *unit, Decl *decl) +void unit_register_external_symbol(SemaContext *context, Decl *decl) { - if (decl_module(decl) == unit->module) return; + if (decl->is_external_visible) return; + Module *active_module = context->current_macro ? context->original_module : context->compilation_unit->module; + if (decl_module(decl) == active_module) return; decl->is_external_visible = true; } diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 561722160..bab55b8d6 100644 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -1565,7 +1565,7 @@ static inline Decl *operator_in_module(SemaContext *c, Module *module, OperatorO { if (extension->operator == operator_overload) { - unit_register_external_symbol(c->compilation_unit, extension); + unit_register_external_symbol(c, extension); return extension; } } @@ -1585,7 +1585,7 @@ Decl *sema_find_operator(SemaContext *context, Type *type, OperatorOverload oper { if (func->operator == operator_overload) { - unit_register_external_symbol(context->compilation_unit, func); + unit_register_external_symbol(context, func); return func; } } @@ -4012,7 +4012,7 @@ Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, con } } if (!sema_analyse_decl(c, symbol)) return poisoned_decl; - unit_register_external_symbol(c->compilation_unit, symbol); + unit_register_external_symbol(c, symbol); return symbol; } diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 9409c7df4..84d2b9bae 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -1033,7 +1033,7 @@ static inline bool sema_expr_analyse_identifier(SemaContext *context, Type *to, } sema_display_deprecated_warning_on_use(context, decl, expr->span); - unit_register_external_symbol(context->compilation_unit, decl); + unit_register_external_symbol(context, decl); if (decl->decl_kind == DECL_VAR) { decl->var.is_read = true; @@ -3291,7 +3291,7 @@ static inline bool sema_expr_analyse_type_access(SemaContext *context, Expr *exp } break; case DECL_FAULT: - unit_register_external_symbol(context->compilation_unit, decl); + unit_register_external_symbol(context, decl); if (is_const) { if (!sema_expr_analyse_enum_constant(context, expr, name, decl)) @@ -4402,7 +4402,7 @@ CHECK_DEEPER: expr->access_expr.parent = current_parent; expr->type = method->type ? type_add_optional(method->type, optional) : NULL; expr->access_expr.ref = method; - if (method->decl_kind == DECL_FUNC) unit_register_external_symbol(context->compilation_unit, method); + if (method->decl_kind == DECL_FUNC) unit_register_external_symbol(context, method); return true; } @@ -4443,7 +4443,7 @@ CHECK_DEEPER: if (member && member->decl_kind == DECL_FUNC) { - unit_register_external_symbol(context->compilation_unit, member); + unit_register_external_symbol(context, member); } // 11. If we didn't find a match... diff --git a/src/compiler/sema_name_resolution.c b/src/compiler/sema_name_resolution.c index 27c0edab1..624da2b3e 100644 --- a/src/compiler/sema_name_resolution.c +++ b/src/compiler/sema_name_resolution.c @@ -547,7 +547,7 @@ INLINE Decl *sema_resolve_symbol_common(SemaContext *context, NameResolve *name_ sema_report_error_on_decl(context, decl, name_resolve); return poisoned_decl; } - unit_register_external_symbol(context->compilation_unit, decl); + unit_register_external_symbol(context, decl); if (decl->is_if && context->call_env.in_if_resolution.a) { sema_error_at(context, context->call_env.in_if_resolution, "This @if expression is dependent on '%s' which is also conditional.", decl->name); diff --git a/test/test_suite/visibility/private_to_extern.c3t b/test/test_suite/visibility/private_to_extern.c3t new file mode 100644 index 000000000..599c230ae --- /dev/null +++ b/test/test_suite/visibility/private_to_extern.c3t @@ -0,0 +1,21 @@ +// #target: macos-x64 + +module test; +import foo; + +fn int main(String[] args) { + foo::one(); + return 0; +} + +module foo; + +macro one() => two(); +macro two() => three(); +fn void three() @private { four(); } +fn void four() @private {} + +/* #expect: foo.ll + +define void @foo.three() +define internal void @foo.four() \ No newline at end of file