From 85a68dbdcd0200a711bacda9c7170129350813c8 Mon Sep 17 00:00:00 2001 From: Miquel Sabaté Solà Date: Fri, 5 Jun 2026 23:32:39 +0200 Subject: Refer to the original file for unused objects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When warning users on unused objects (e.g. variables, proc's), we have to pick up the source of origin for this warning. In places where the original PNode is not available, then we go with the last source we have at hand, as that's the usual way to go (i.e. the error occurred at the current source/context). That being said, for unused objects that's not desirable, because we might otherwise claim the error to happen on the file we first targetted, but it's way more useful to understand where the object was defined. Hence, when defining a variable, address or proc, let's actually store the PNode associated with it as well. This way the checker can hopefully get the source from this PNode and be more clear to the user. Signed-off-by: Miquel Sabaté Solà --- lib/xixanta/src/assembler.rs | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-) (limited to 'lib/xixanta/src/assembler.rs') diff --git a/lib/xixanta/src/assembler.rs b/lib/xixanta/src/assembler.rs index c53f143..e8ecd06 100644 --- a/lib/xixanta/src/assembler.rs +++ b/lib/xixanta/src/assembler.rs @@ -495,7 +495,16 @@ impl<'a> Assembler<'a> { if let Err(message) = self.context.set_variable( &node.value, - &Object::new(self.current_mapping, self.current_segment, object_type), + &Object { + bundle: Bundle::default(), + node: Some(node.clone()), + mapping: self.current_mapping, + segment: self.current_segment, + object_type, + asan_ignore: false, + asan_reserve: 1, + accessed: 0, + }, false, ) { return Err(Error { @@ -619,7 +628,7 @@ impl<'a> Assembler<'a> { &node.value, &Object { bundle: value, - node: None, + node: Some(node.clone()), mapping: self.current_mapping, segment: self.current_segment, object_type: ObjectType::Value, @@ -1199,13 +1208,24 @@ impl<'a> Assembler<'a> { // (e.g. nasm's '--allow-unused' flag), or the magic // 'asan:ignore' comment is given. if !self.allow_unused && !bundle.asan_ignore && bundle.accessed == 0 { + // For unused stuff we need to point to the source of the + // definition, not the current context. This is usually + // provided on the 'bundle.node' member, but we can always + // pick the first source if that's not provided for some + // unknown reason. + let source = self.sources[match &bundle.node { + Some(node) => node.source, + None => 0, + }] + .clone(); + // If this was a .proc definition then we are certain that // this is dead code, which is a really crappy situation. if matches!(bundle.object_type, ObjectType::Proc) { errors.push(Error { line: 0, message: format!("proc '{full_name}' is unused"), - source: self.sources[0].clone(), + source, expanded_from: self.macro_context.clone(), global: true, }); @@ -1216,7 +1236,7 @@ impl<'a> Assembler<'a> { self.warnings.push(Error { line: 0, message: format!("{} '{full_name}' is unused", bundle.object_type), - source: self.sources[0].clone(), + source, expanded_from: self.macro_context.clone(), global: true, }); -- cgit v1.2.3