From 6cb4215f55876a7fffb1fd33f2bd061283d2389f Mon Sep 17 00:00:00 2001 From: Miquel Sabaté Solà Date: Tue, 18 Aug 2026 16:41:34 +0200 Subject: Validate labels when walking through the context MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The parser does not validate label names completely (it only takes care of validating that it something that makes sense syntactically). The assembler can tell whether the label is actually taking a reserved name, or an invalid hexadecimal constant, etc. Before this commit a user would get a cryptic "invalid identifier" message when referencing an invalid label (e.g. "jmp 1234"). Fix this by validating the identifier there, but also when the label was defined before any of this. Signed-off-by: Miquel Sabaté Solà --- lib/xixanta/src/assembler.rs | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/xixanta/src/assembler.rs b/lib/xixanta/src/assembler.rs index 3cf1e0b..0c5227e 100644 --- a/lib/xixanta/src/assembler.rs +++ b/lib/xixanta/src/assembler.rs @@ -605,6 +605,21 @@ impl<'a> Assembler<'a> { }); continue; } + + // If this is a named label with an invalid identifier, + // report it now. + if !node.value.is_empty() + && let Err(err) = node.value.is_valid_identifier(true) + { + errors.push(Error { + message: format!("invalid identifier: {err}"), + line: node.value.line, + source: self.source_for(node), + expanded_from: self.macro_context.clone(), + global: false, + }); + } + if let Err(err) = self.define_variable(node, ObjectType::Address) { errors.push(err); } @@ -1825,10 +1840,13 @@ impl<'a> Assembler<'a> { Ok(self.evaluate_decimal(node)?) } else if node.value.is_anonymous_relative_reference() { Ok(self.evaluate_anonymous_relative_reference(node)?) - } else if node.value.is_valid_identifier(true).is_err() { - // If this is not a valid identifier, just error out. + } else if let Err(err) = node.value.is_valid_identifier(true) { + // If this is not a valid identifier, just error + // out. Note that this should have been already covered + // when defining the identifier, but just as a sanity + // check. Err(Error { - message: "invalid identifier".to_string(), + message: format!("invalid identifier: {err}"), line: node.value.line, source: self.source_for(node), expanded_from: self.macro_context.clone(), @@ -5027,6 +5045,17 @@ label: ); } + #[test] + fn bad_label_name() { + let res = just_assemble("x: nop"); + + assert_eq!(res.errors.len(), 1); + assert_eq!( + res.errors[0].to_string(), + "invalid identifier: cannot use reserved name 'x' (line 4)" + ); + } + // Control statements #[test] -- cgit v1.2.3