diff --git a/go/ql/lib/semmle/go/Overlay.qll b/go/ql/lib/semmle/go/Overlay.qll index f4aa6b88a557..c3f27a15e52f 100644 --- a/go/ql/lib/semmle/go/Overlay.qll +++ b/go/ql/lib/semmle/go/Overlay.qll @@ -54,3 +54,39 @@ private predicate discardLocatable(@locatable locatable) { discardableLocatable(file, locatable) and discardableFile(path) ) } + +/** + * Holds if the given `structtype` should be discarded, because it is part of + * the overlay base and is only defined in files that were extracted as part of + * the overlay database. + * + * Note that struct types use structural typing. In other words, two different + * files can define defined types whose underlying types are struct types with + * the same fields (names, types and tags), and they will be considered to be + * the exact same struct type. + */ +private predicate discardableStructType(@structtype structtype) { + not isOverlay() and + forex(@definedtype dt, @typeobject to, @ident declIdent, string path | + underlying_type(dt, structtype) and + type_objects(dt, to) and + defs(declIdent, to) and + files(getFile(declIdent), path) + | + discardableFile(path) + ) +} + +overlay[discard_entity] +private predicate discardStructType(@structtype structtype) { discardableStructType(structtype) } + +/** + * Holds if the given `field` should be discarded, because it is defined in a + * struct type which should be discarded. + */ +overlay[discard_entity] +private predicate discardField(@varobject field) { + exists(@structtype structtype | fieldstructs(field, structtype) | + discardableStructType(structtype) + ) +}