diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 51226c6ab..8f6412b31 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -2143,6 +2143,10 @@ gb_internal AsmTemplateEntityDeclKind check_asm_find_kind(Entity *entity, Array< gb_internal void check_asm_specs(CheckerContext *ctx, Scope *scope, Slice const &specs, Array *asm_template_entity_decls) { + StringSet pin_set = {}; + string_set_init(&pin_set, specs.count); + defer (string_set_destroy(&pin_set)); + for (Ast *spec_ : specs) { if (spec_->kind != Ast_AsmSpec) { continue; @@ -2169,6 +2173,11 @@ gb_internal void check_asm_specs(CheckerContext *ctx, Scope *scope, Slice if (pin == "any") { pin = {}; } + if (pin.len != 0) { + if (string_set_update(&pin_set, pin)) { + error(spec->value, "Pinned register %%%.*s has already be assigned", LIT(pin)); + } + } } if (spec->tied_name == nullptr) { @@ -2488,19 +2497,38 @@ gb_internal void check_asm_template(CheckerContext *ctx, Entity *entity, DeclInf check_asm_specs(ctx, ate->param_scope, at->specs, &ate->decls); { // check clobbers + StringSet reg_set = {}; + string_set_init(®_set, 16); + defer (string_set_destroy(®_set)); + + bool clobber_cc = false; + bool clobber_memory = false; + for (Ast *clobber_ : at->clobbers) { ast_node(clobber, AsmClobber, clobber_); switch (clobber->value->kind) { case Ast_AsmRegister: - // TODO(bill): register check + { + String reg = clobber->value->AsmRegister.name.string; + if (string_set_update(®_set, reg)) { + error(clobber->value, "#clobber %%%.*s has already been defined", LIT(reg)); + } + // TODO(bill): register check for validity + } break; case Ast_Ident: { String str = clobber->value->Ident.token.string; if (str == "cc") { - // okay + if (clobber_cc) { + error(clobber->value, "#clobber cc has already been defined"); + } + clobber_cc = true; } else if (str == "memory") { - // okay + if (clobber_memory) { + error(clobber->value, "#clobber memory has already been defined"); + } + clobber_memory = true; } else { error(clobber->value, "Expected either a register, 'cc', or 'memory' for a '#clobber' specification, got '%.*s'", LIT(str)); }