From 4c009d5bc9bb2b0d41b389a7e8866adcc0e24ea6 Mon Sep 17 00:00:00 2001 From: Nick Rolfe Date: Fri, 5 Sep 2025 12:07:12 +0100 Subject: [PATCH] Go: implement overlay discarding for @locatable --- go/ql/lib/semmle/go/Locations.qll | 1 + go/ql/lib/semmle/go/Overlay.qll | 35 +++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 go/ql/lib/semmle/go/Overlay.qll diff --git a/go/ql/lib/semmle/go/Locations.qll b/go/ql/lib/semmle/go/Locations.qll index 817fea56f00..7503421c0ff 100644 --- a/go/ql/lib/semmle/go/Locations.qll +++ b/go/ql/lib/semmle/go/Locations.qll @@ -1,6 +1,7 @@ /** Provides classes for working with locations and program elements that have locations. */ import go +private import semmle.go.Overlay /** * A location as given by a file, a start line, a start column, diff --git a/go/ql/lib/semmle/go/Overlay.qll b/go/ql/lib/semmle/go/Overlay.qll new file mode 100644 index 00000000000..fa3719bd00c --- /dev/null +++ b/go/ql/lib/semmle/go/Overlay.qll @@ -0,0 +1,35 @@ +/** + * Defines entity discard predicates for Go overlay analysis. + */ +overlay[local] +module; + +/** + * A local predicate that always holds for the overlay variant and never holds for the base variant. + * This is used to define local predicates that behave differently for the base and overlay variant. + */ +private predicate isOverlay() { databaseMetadata("isOverlay", "true") } + +/** Gets the file containing the given `locatable`. */ +private @file getFile(@locatable locatable) { + exists(@location_default location | has_location(locatable, location) | + locations_default(location, result, _, _, _, _) + ) +} + +/** Holds if the `locatable` is in the `file` and is part of the overlay base database. */ +private predicate discardableLocatable(@file file, @locatable locatable) { + not isOverlay() and + file = getFile(locatable) +} + +/** + * Holds if the given `locatable` should be discarded, because it is part of the overlay base and is + * in a file that was also extracted as part of the overlay database. + */ +overlay[discard_entity] +private predicate discardLocatable(@locatable locatable) { + exists(@file file, string path | files(file, path) | + discardableLocatable(file, locatable) and overlayChangedFiles(path) + ) +}