MCPcopy Index your code
hub / github.com/Rust-API/Rust-API-Bypass-Checker / refine_paths

Method refine_paths

src/analysis/memory/path.rs:546–666  ·  view source on GitHub ↗

Refine paths that reference other paths and canonicalize the refinements. I.e. when a reference is passed to a function that then returns or leaks it back to the caller in the qualifier of a path then we want to dereference the qualifier in order to normalize the path and not have more than one path for the same location.

(&self, environment: &AbstractDomain<DomainType>)

Source from the content-addressed store, hash-verified

544 /// we want to dereference the qualifier in order to normalize the path
545 /// and not have more than one path for the same location.
546 fn refine_paths(&self, environment: &AbstractDomain<DomainType>) -> Rc<Path> {
547 if let Some(mut val) = environment.value_at(&self) {
548 // If the environment has self as a key, then self is canonical, since we should only
549 // use canonical paths as keys. The value at the canonical key, however, could just
550 // be a reference to another path, which is something that happens during refinement.
551 if let Expression::Cast { operand, .. } = &val.expression {
552 val = operand.clone();
553 }
554 return match &val.expression {
555 Expression::HeapBlock { .. } => Path::get_as_path(val.refine_paths(environment)),
556 Expression::Variable { path, .. } | Expression::Widen { path, .. } => {
557 if let PathEnum::QualifiedPath { selector, .. } = &path.value {
558 if *selector.as_ref() == PathSelector::Deref {
559 // If the path is a deref, it is not just an alias for self, so keep self
560 return self.clone();
561 }
562 }
563 path.clone()
564 }
565 _ => self.clone(), // self is canonical
566 };
567 }
568 // self is a path that is not a key in the environment. This could be because it is not
569 // canonical, which can only be the case if self is a qualified path.
570 match &self.value {
571 // PathEnum::Offset { value } => Path::get_as_path(value.refine_paths(environment)),
572 PathEnum::QualifiedPath {
573 qualifier,
574 selector,
575 ..
576 } => {
577 let refined_selector = selector.refine_paths(environment);
578 let refined_qualifier = qualifier.refine_paths(environment);
579
580 // The qualifier is now canonical. But in the context of a selector, we
581 // might be able to simplify the qualifier by dropping an explicit dereference
582 // or an explicit reference.
583 if let PathEnum::QualifiedPath {
584 qualifier: base_qualifier,
585 selector: base_selector,
586 ..
587 } = &refined_qualifier.value
588 {
589 if *base_selector.as_ref() == PathSelector::Deref {
590 // no need for an explicit deref in a qualifier
591 return Path::new_qualified(
592 base_qualifier.clone(),
593 refined_selector.clone(),
594 );
595 }
596 }
597 if let Some(val) = environment.value_at(&refined_qualifier) {
598 match &val.expression {
599 Expression::Variable { path, .. } => {
600 // if path is a deref we just drop it because it becomes implicit
601 if let PathEnum::QualifiedPath {
602 qualifier,
603 selector: var_path_selector,

Callers 15

visit_placeMethod · 0.45
get_path_for_placeMethod · 0.45
visit_projectionMethod · 0.45
visit_unary_opMethod · 0.45
visit_repeatMethod · 0.45
visit_address_ofMethod · 0.45
get_lenMethod · 0.45
copy_or_move_elementsMethod · 0.45

Calls 2

value_atMethod · 0.80
is_path_aliasMethod · 0.80

Tested by

no test coverage detected