Skip to content
This repository was archived by the owner on Jan 5, 2023. It is now read-only.

Commit 59f9c60

Browse files
committed
Introduce instruction type for component access
This is the union of a field-access and an element-access instruction
1 parent 455cf0c commit 59f9c60

File tree

2 files changed

+28
-26
lines changed

2 files changed

+28
-26
lines changed

ql/src/semmle/go/controlflow/IR.qll

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -253,23 +253,32 @@ module IR {
253253
)
254254
}
255255

256+
/**
257+
* An IR instruction that reads a component from a composite object.
258+
*
259+
* This is either a field of a struct, or an element of an array, map, slice or string.
260+
*/
261+
class ComponentReadInstruction extends ReadInstruction, EvalInstruction {
262+
ComponentReadInstruction() {
263+
e instanceof IndexExpr
264+
or
265+
e.(SelectorExpr).getBase() instanceof ValueExpr and
266+
not e.(SelectorExpr).getSelector() = any(Method method).getAReference()
267+
}
268+
269+
/** Gets the instruction computing the base value on which the field or element is read. */
270+
Instruction getBase() { result = selectorBase(e) }
271+
}
272+
256273
/**
257274
* An IR instruction that reads the value of a field.
258275
*
259276
* On snapshots with incomplete type information, method expressions may sometimes be
260277
* misclassified as field reads.
261278
*/
262-
class FieldReadInstruction extends ReadInstruction, EvalInstruction {
279+
class FieldReadInstruction extends ComponentReadInstruction {
263280
override SelectorExpr e;
264281

265-
FieldReadInstruction() {
266-
e.getBase() instanceof ValueExpr and
267-
not e.getSelector() = any(Method method).getAReference()
268-
}
269-
270-
/** Gets the instruction computing the base value on which the field is read. */
271-
Instruction getBase() { result = selectorBase(e) }
272-
273282
/** Gets the field being read. */
274283
Field getField() { e.getSelector() = result.getAReference() }
275284

@@ -299,12 +308,9 @@ module IR {
299308
/**
300309
* An IR instruction that reads an element of an array, slice, map or string.
301310
*/
302-
class ElementReadInstruction extends ReadInstruction, EvalInstruction {
311+
class ElementReadInstruction extends ComponentReadInstruction {
303312
override IndexExpr e;
304313

305-
/** Gets the instruction computing the base value on which the element is looked up. */
306-
Instruction getBase() { result = selectorBase(e) }
307-
308314
/** Gets the instruction computing the index of the element being looked up. */
309315
Instruction getIndex() { result = evalExprInstruction(e.getIndex()) }
310316

ql/src/semmle/go/dataflow/internal/DataFlowUtil.qll

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -593,30 +593,29 @@ class ReadNode extends InstructionNode {
593593
/**
594594
* A data-flow node that reads the value of a field from a struct, or an element from an array, slice, map or string.
595595
*/
596-
abstract class ReadFromAggregateNode extends ReadNode {
596+
class ComponentReadNode extends ReadNode {
597+
override IR::ComponentReadInstruction insn;
598+
597599
/** Gets the data-flow node representing the base from which the field or element is read. */
598-
abstract Node getBase();
600+
Node getBase() { result = instructionNode(insn.getBase()) }
599601
}
600602

601603
/**
602-
* Gets the data-flow node representing the bottom of a stack of zero or more `ReadFromAggregateNode`s.
604+
* Gets the data-flow node representing the bottom of a stack of zero or more `ComponentReadNode`s.
603605
*
604606
* For example, in the expression a.b[c].d[e], this would return the dataflow node for the read from `a`.
605607
*/
606608
Node getUnderlyingNode(ReadNode read) {
607-
(result = read or result = read.(ReadFromAggregateNode).getBase+()) and
608-
not result instanceof ReadFromAggregateNode
609+
(result = read or result = read.(ComponentReadNode).getBase+()) and
610+
not result instanceof ComponentReadNode
609611
}
610612

611613
/**
612614
* A data-flow node that reads an element of an array, map, slice or string.
613615
*/
614-
class ElementReadNode extends ReadFromAggregateNode {
616+
class ElementReadNode extends ComponentReadNode {
615617
override IR::ElementReadInstruction insn;
616618

617-
/** Gets the data-flow node representing the base from which the element is read. */
618-
override Node getBase() { result = instructionNode(insn.getBase()) }
619-
620619
/** Gets the data-flow node representing the index of the element being read. */
621620
Node getIndex() { result = instructionNode(insn.getIndex()) }
622621

@@ -762,12 +761,9 @@ class AddressOperationNode extends UnaryOperationNode, ExprNode {
762761
/**
763762
* A data-flow node that reads the value of a field.
764763
*/
765-
class FieldReadNode extends ReadFromAggregateNode {
764+
class FieldReadNode extends ComponentReadNode {
766765
override IR::FieldReadInstruction insn;
767766

768-
/** Gets the base node from which the field is read. */
769-
override Node getBase() { result = instructionNode(insn.getBase()) }
770-
771767
/** Gets the field this node reads. */
772768
Field getField() { result = insn.getField() }
773769

0 commit comments

Comments
 (0)