From fddff6ee2d87b92015759660e39ce37f4401e833 Mon Sep 17 00:00:00 2001 From: Nick Fitzgerald Date: Tue, 5 Oct 2021 16:35:07 -0700 Subject: [PATCH] Fix a panic when checking the call graph for an extractor with type errors in its definition --- cranelift/isle/isle/src/ast.rs | 6 +++--- cranelift/isle/isle/src/sema.rs | 26 +++++++++++++++++++++++--- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/cranelift/isle/isle/src/ast.rs b/cranelift/isle/isle/src/ast.rs index 5af7eaf6d7..4b2aa84ca0 100644 --- a/cranelift/isle/isle/src/ast.rs +++ b/cranelift/isle/isle/src/ast.rs @@ -128,10 +128,10 @@ impl Pattern { } /// Call `f` for each of the terms in this pattern. - pub fn terms(&self, f: &mut dyn FnMut(&Ident)) { + pub fn terms(&self, f: &mut dyn FnMut(Pos, &Ident)) { match self { - Pattern::Term { sym, args, .. } => { - f(sym); + Pattern::Term { sym, args, pos } => { + f(*pos, sym); for arg in args { if let TermArgPattern::Pattern(p) = arg { p.terms(f); diff --git a/cranelift/isle/isle/src/sema.rs b/cranelift/isle/isle/src/sema.rs index 14062ea3f0..f437a23279 100644 --- a/cranelift/isle/isle/src/sema.rs +++ b/cranelift/isle/isle/src/sema.rs @@ -847,17 +847,29 @@ impl TermEnv { return; } }; - let termdata = &mut self.terms[term.index()]; + let template = ext.template.make_macro_template(&ext.args[..]); log::trace!("extractor def: {:?} becomes template {:?}", def, template); let mut callees = HashSet::new(); - template.terms(&mut |t| { + template.terms(&mut |pos, t| { let t = tyenv.intern_mut(t); callees.insert(t); + + if !self.term_map.contains_key(&t) { + tyenv.report_error( + pos, + format!( + "`{}` extractor definition references unknown term `{}`", + ext.term.0, + tyenv.syms[t.index()] + ), + ); + } }); extractor_call_graph.insert(sym, callees); + let termdata = &mut self.terms[term.index()]; match &termdata.kind { &TermKind::Declared => { termdata.kind = TermKind::InternalExtractor { template }; @@ -892,7 +904,15 @@ impl TermEnv { })); } } else { - let term = self.term_map[&caller]; + let term = match self.term_map.get(&caller) { + Some(t) => t, + None => { + // Some other error must have already been recorded + // if we don't have the caller's term data. + assert!(!tyenv.errors.is_empty()); + continue 'outer; + } + }; let pos = match &self.terms[term.index()].kind { TermKind::InternalExtractor { template } => template.pos(), _ => unreachable!(),