Deduplicate and document helper types

This commit is contained in:
Chris Smowton
2021-03-17 22:21:00 +00:00
committed by Owen Mansel-Chan
parent 9a427931b7
commit 6645613eb8
4 changed files with 34 additions and 32 deletions

View File

@@ -593,6 +593,29 @@ class SelectorExpr extends @selectorexpr, Expr {
override string getAPrimaryQlClass() { result = "SelectorExpr" }
}
/**
* A selector expression that refers to a promoted field. These selectors may implicitly
* address an embedded struct of their base type (e.g. the selector `x.field` may implicitly
* address `x.Embedded.field`). Note they may also explicitly address `field`; being a
* `PromotedFieldSelector` only indicates the addressed field may be promoted, not that it
* is promoted in this particular context.
*/
class PromotedFieldSelector extends SelectorExpr {
PromotedFieldSelector() { this.refersTo(any(PromotedField f)) }
/**
* Gets the underlying struct type of this selector's base. Note because this selector
* addresses a promoted field, the addressed field may not directly occur in the returned
* struct type.
*/
StructType getSelectedStructType() {
exists(Type baseType | baseType = this.getBase().getType().getUnderlyingType() |
pragma[only_bind_into](result) =
[baseType, baseType.(PointerType).getBaseType().getUnderlyingType()]
)
}
}
/**
* An index expression, that is, a base expression followed by an index.
*

View File

@@ -353,6 +353,15 @@ class Field extends Variable {
}
}
/**
* A field that belongs to a struct that may be embedded within another struct.
*
* When a selector addresses such a field, it is possible it is implicitly addressing a nested struct.
*/
class PromotedField extends Field {
PromotedField() { this = any(StructType t).getFieldOfEmbedded(_, _, _, _) }
}
/** A built-in or declared function. */
class Function extends ValueEntity, @functionobject {
/** Gets a call to this function. */

View File

@@ -48,16 +48,9 @@ private predicate isCond(Expr e) {
e = any(ParenExpr par | isCond(par)).getExpr()
}
private StructType getSelectedStructType(PromotedFieldSelector e) {
exists(Type baseType | baseType = e.getBase().getType().getUnderlyingType() |
pragma[only_bind_into](result) =
[baseType, baseType.(PointerType).getBaseType().getUnderlyingType()]
)
}
private predicate implicitFieldSelection(PromotedFieldSelector e, int i, Field implicitField) {
exists(StructType baseType, PromotedField child |
baseType = getSelectedStructType(e) and
baseType = e.getSelectedStructType() and
(
e.refersTo(child)
or
@@ -68,14 +61,6 @@ private predicate implicitFieldSelection(PromotedFieldSelector e, int i, Field i
)
}
private class PromotedFieldSelector extends SelectorExpr {
PromotedFieldSelector() { this.refersTo(any(PromotedField f)) }
}
private class PromotedField extends Field {
PromotedField() { this = any(StructType t).getFieldOfEmbedded(_, _, _, _) }
}
/**
* A node in the intra-procedural control-flow graph of a Go function or file.
*

View File

@@ -271,23 +271,8 @@ module IR {
result = simpleSelectorBase(e)
}
private class PromotedField extends Field {
PromotedField() { this = any(StructType t).getFieldOfEmbedded(_, _, _, _) }
}
private class PromotedFieldSelector extends SelectorExpr {
PromotedFieldSelector() { this.refersTo(any(PromotedField f)) }
}
private StructType getSelectedStructType(PromotedFieldSelector e) {
exists(Type baseType | baseType = e.getBase().getType().getUnderlyingType() |
pragma[only_bind_into](result) =
[baseType, baseType.(PointerType).getBaseType().getUnderlyingType()]
)
}
private Instruction promotedFieldSelectorBase(PromotedFieldSelector se, Field field) {
exists(StructType baseStructType | baseStructType = getSelectedStructType(se) |
exists(StructType baseStructType | baseStructType = se.getSelectedStructType() |
if field = baseStructType.getOwnField(_, _)
then
result = MkImplicitDeref(se.getBase())