diff --git a/releasenotes.md b/releasenotes.md index fd3236b35..e77d10405 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -57,6 +57,7 @@ - Fix stringify of $vaexpr #2301. - Segfault when failing to cast subexpression to 'isz' in pointer subtraction #2305. - Fix unexpected display of macro definition when passing a poisoned expression #2305. +- `@links` on macros would not be added to calling functions. ### Stdlib changes - Improve contract for readline. #2280 diff --git a/src/compiler/copying.c b/src/compiler/copying.c index 018fe2e43..bee9dd8a4 100644 --- a/src/compiler/copying.c +++ b/src/compiler/copying.c @@ -862,13 +862,17 @@ static ResolvedAttrData *copy_attrs_resolved(CopyStruct *c, ResolvedAttrData *da { if (!data) return NULL; ResolvedAttrData *copy = MALLOCS(ResolvedAttrData); + const char **new_links = NULL; + FOREACH(const char *, link, data->links) vec_add(new_links, link); *copy = (ResolvedAttrData) { .tags = copy_attributes(c, data->tags), .deprecated = data->deprecated, - .links = data->links, + .links = new_links, .section = data->section, .wasm_module = data->wasm_module }; + const char **new = NULL; + return copy; } diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index f197d0fb2..2456f5c2d 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -2550,6 +2550,26 @@ bool sema_expr_analyse_macro_call(SemaContext *context, Expr *call_expr, Expr *s bool call_var_optional, bool *no_match_ref) { bool is_always_const = decl->func_decl.signature.attrs.always_const; + if (decl->resolved_attributes && decl->attrs_resolved && decl->attrs_resolved->links) + { + Decl *func = context->call_env.current_function; + if (!func) + { + RETURN_SEMA_ERROR(call_expr, "Cannot call macro with '@links' outside of a function."); + } + assert(func->resolved_attributes); + if (!func->attrs_resolved) + { + func->attrs_resolved = MALLOCS(ResolvedAttrData); + *func->attrs_resolved = (ResolvedAttrData) { .overload = INVALID_SPAN }; + } + const char **updated = func->attrs_resolved->links; + FOREACH(const char *, link, decl->attrs_resolved->links) + { + vec_add(updated, link); + } + func->attrs_resolved->links = updated; + } bool is_outer = call_expr->call_expr.is_outer_call; ASSERT_SPAN(call_expr, decl->decl_kind == DECL_MACRO);