C++: Remove PositionalArgumentWithoutWriteSideEffectNode (since not all arguments need a PostUpdateNode). Also generalized the added flow rule in simpleLocalFlowStep since there isn't always a ChiInstruction - for instance of it's a write to a struct that only has a single field.

This commit is contained in:
Mathias Vorreiter Pedersen
2020-03-26 11:39:20 +01:00
parent f92dd3c565
commit fbef146a49
2 changed files with 50 additions and 21 deletions

View File

@@ -218,7 +218,17 @@ abstract class PostUpdateNode extends InstructionNode {
override string toString() { result = getPreUpdateNode().toString() + " [post update]" }
}
abstract class PartialDefinitionNode extends PostUpdateNode, TInstructionNode { }
abstract private class PartialDefinitionNode extends PostUpdateNode, TInstructionNode {
final Instruction getInstructionOrChi() {
exists(ChiInstruction chi |
// TODO: This should be a non-conflated ChiInstruction once #3123 is merged
chi.getPartial() = getInstruction() and
result = chi
)
or
result = getInstruction()
}
}
class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
override StoreInstruction instr;
@@ -268,22 +278,6 @@ class DefinitionByReferenceNode extends PartialDefinitionNode {
override string toString() { result = "ref arg " + getPreUpdateNode().toString() }
}
class PositionalArgumentWithoutWriteSideEffectNode extends PartialDefinitionNode {
override CallInstruction instr;
PositionalArgumentOperand op;
PositionalArgumentWithoutWriteSideEffectNode() {
instr.getAnOperand() = op and
not exists(WriteSideEffectInstruction write |
write.getIndex() = op.getIndex() and write.getPrimaryInstruction() = instr
)
}
override Node getPreUpdateNode() { result.asInstruction() = op.getDef() }
override string toString() { result = "no change to " + op.toString() }
}
/**
* A `Node` corresponding to a variable in the program, as opposed to the
* value of that variable at some particular point. This can be used for
@@ -365,10 +359,10 @@ predicate localFlowStep(Node nodeFrom, Node nodeTo) { simpleLocalFlowStep(nodeFr
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
simpleInstructionLocalFlowStep(nodeFrom.asInstruction(), nodeTo.asInstruction())
or
exists(ChiInstruction chi, LoadInstruction load |
chi.getPartial() = nodeFrom.(PartialDefinitionNode).getInstruction() and
// TODO: This can probably be getSourceValue() after #3112 is merged
load.getSourceValueOperand().getAnyDef() = chi and
exists(LoadInstruction load |
// TODO: These can probably be getSourceValue() after #3112 is merged
load.getSourceValueOperand().getAnyDef() =
nodeFrom.(PartialDefinitionNode).getInstructionOrChi() and
nodeTo.asInstruction() = load.getSourceAddress().(FieldAddressInstruction).getObjectAddress()
)
}

View File

@@ -15,27 +15,48 @@ edges
| aliasing.cpp:26:19:26:20 | ref arg (reference to) [m1] : void | aliasing.cpp:30:8:30:9 | s2 [m1] : void |
| aliasing.cpp:29:8:29:9 | s1 [m1] : void | aliasing.cpp:29:11:29:12 | m1 |
| aliasing.cpp:30:8:30:9 | s2 [m1] : void | aliasing.cpp:30:11:30:12 | m1 |
| aliasing.cpp:37:3:37:24 | (reference dereference) [post update] : void | aliasing.cpp:37:3:37:24 | (reference dereference) [post update] [m1] : void |
| aliasing.cpp:37:3:37:24 | (reference dereference) [post update] : void | aliasing.cpp:38:11:38:12 | m1 |
| aliasing.cpp:37:3:37:24 | (reference dereference) [post update] [m1] : void | aliasing.cpp:38:8:38:9 | s1 [m1] : void |
| aliasing.cpp:37:13:37:22 | call to user_input : void | aliasing.cpp:37:3:37:24 | (reference dereference) [post update] : void |
| aliasing.cpp:37:13:37:22 | call to user_input : void | aliasing.cpp:38:11:38:12 | m1 |
| aliasing.cpp:38:8:38:9 | s1 [m1] : void | aliasing.cpp:38:11:38:12 | m1 |
| aliasing.cpp:42:3:42:22 | s2 [post update] : void | aliasing.cpp:42:3:42:22 | s2 [post update] [m1] : void |
| aliasing.cpp:42:3:42:22 | s2 [post update] : void | aliasing.cpp:43:13:43:14 | m1 |
| aliasing.cpp:42:3:42:22 | s2 [post update] [m1] : void | aliasing.cpp:43:8:43:11 | (reference dereference) [m1] : void |
| aliasing.cpp:42:11:42:20 | call to user_input : void | aliasing.cpp:42:3:42:22 | s2 [post update] : void |
| aliasing.cpp:42:11:42:20 | call to user_input : void | aliasing.cpp:43:13:43:14 | m1 |
| aliasing.cpp:43:8:43:11 | (reference dereference) [m1] : void | aliasing.cpp:43:13:43:14 | m1 |
| aliasing.cpp:79:3:79:22 | s [post update] : void | aliasing.cpp:79:3:79:22 | s [post update] [m1] : void |
| aliasing.cpp:79:3:79:22 | s [post update] : void | aliasing.cpp:80:12:80:13 | m1 |
| aliasing.cpp:79:3:79:22 | s [post update] [m1] : void | aliasing.cpp:80:10:80:10 | s [m1] : void |
| aliasing.cpp:79:11:79:20 | call to user_input : void | aliasing.cpp:79:3:79:22 | s [post update] : void |
| aliasing.cpp:79:11:79:20 | call to user_input : void | aliasing.cpp:80:12:80:13 | m1 |
| aliasing.cpp:80:10:80:10 | s [m1] : void | aliasing.cpp:80:12:80:13 | m1 |
| aliasing.cpp:86:3:86:21 | (reference dereference) [post update] : void | aliasing.cpp:86:3:86:21 | (reference dereference) [post update] [m1] : void |
| aliasing.cpp:86:3:86:21 | (reference dereference) [post update] : void | aliasing.cpp:87:12:87:13 | m1 |
| aliasing.cpp:86:3:86:21 | (reference dereference) [post update] [m1] : void | aliasing.cpp:87:10:87:10 | s [m1] : void |
| aliasing.cpp:86:10:86:19 | call to user_input : void | aliasing.cpp:86:3:86:21 | (reference dereference) [post update] : void |
| aliasing.cpp:86:10:86:19 | call to user_input : void | aliasing.cpp:87:12:87:13 | m1 |
| aliasing.cpp:87:10:87:10 | s [m1] : void | aliasing.cpp:87:12:87:13 | m1 |
| aliasing.cpp:92:3:92:23 | s [post update] : void | aliasing.cpp:92:3:92:23 | s [post update] [m1] : void |
| aliasing.cpp:92:3:92:23 | s [post update] : void | aliasing.cpp:93:12:93:13 | m1 |
| aliasing.cpp:92:3:92:23 | s [post update] [m1] : void | aliasing.cpp:93:10:93:10 | s [m1] : void |
| aliasing.cpp:92:12:92:21 | call to user_input : void | aliasing.cpp:92:3:92:23 | s [post update] : void |
| aliasing.cpp:92:12:92:21 | call to user_input : void | aliasing.cpp:93:12:93:13 | m1 |
| aliasing.cpp:93:10:93:10 | s [m1] : void | aliasing.cpp:93:12:93:13 | m1 |
| struct_init.c:20:20:20:29 | VariableAddress [post update] : void | struct_init.c:20:20:20:29 | VariableAddress [post update] [a] : void |
| struct_init.c:20:20:20:29 | VariableAddress [post update] : void | struct_init.c:22:11:22:11 | a |
| struct_init.c:20:20:20:29 | VariableAddress [post update] [a] : void | struct_init.c:22:8:22:9 | ab [a] : void |
| struct_init.c:20:20:20:29 | call to user_input : void | struct_init.c:20:20:20:29 | VariableAddress [post update] : void |
| struct_init.c:20:20:20:29 | call to user_input : void | struct_init.c:22:11:22:11 | a |
| struct_init.c:22:8:22:9 | ab [a] : void | struct_init.c:22:11:22:11 | a |
| struct_init.c:27:7:27:16 | FieldAddress [post update] : void | struct_init.c:27:7:27:16 | FieldAddress [post update] [a] : void |
| struct_init.c:27:7:27:16 | FieldAddress [post update] : void | struct_init.c:31:23:31:23 | a |
| struct_init.c:27:7:27:16 | FieldAddress [post update] [a] : void | struct_init.c:31:14:31:21 | nestedAB [a] : void |
| struct_init.c:27:7:27:16 | call to user_input : void | struct_init.c:27:7:27:16 | FieldAddress [post update] : void |
| struct_init.c:27:7:27:16 | call to user_input : void | struct_init.c:31:23:31:23 | a |
| struct_init.c:31:14:31:21 | nestedAB [a] : void | struct_init.c:31:23:31:23 | a |
nodes
| A.cpp:126:5:126:5 | ref arg b [c] : void | semmle.label | ref arg b [c] : void |
| A.cpp:126:12:126:18 | new : void | semmle.label | new : void |
@@ -57,25 +78,39 @@ nodes
| aliasing.cpp:30:8:30:9 | s2 [m1] : void | semmle.label | s2 [m1] : void |
| aliasing.cpp:30:11:30:12 | m1 | semmle.label | m1 |
| aliasing.cpp:37:3:37:24 | (reference dereference) [post update] : void | semmle.label | (reference dereference) [post update] : void |
| aliasing.cpp:37:3:37:24 | (reference dereference) [post update] [m1] : void | semmle.label | (reference dereference) [post update] [m1] : void |
| aliasing.cpp:37:13:37:22 | call to user_input : void | semmle.label | call to user_input : void |
| aliasing.cpp:38:8:38:9 | s1 [m1] : void | semmle.label | s1 [m1] : void |
| aliasing.cpp:38:11:38:12 | m1 | semmle.label | m1 |
| aliasing.cpp:42:3:42:22 | s2 [post update] : void | semmle.label | s2 [post update] : void |
| aliasing.cpp:42:3:42:22 | s2 [post update] [m1] : void | semmle.label | s2 [post update] [m1] : void |
| aliasing.cpp:42:11:42:20 | call to user_input : void | semmle.label | call to user_input : void |
| aliasing.cpp:43:8:43:11 | (reference dereference) [m1] : void | semmle.label | (reference dereference) [m1] : void |
| aliasing.cpp:43:13:43:14 | m1 | semmle.label | m1 |
| aliasing.cpp:79:3:79:22 | s [post update] : void | semmle.label | s [post update] : void |
| aliasing.cpp:79:3:79:22 | s [post update] [m1] : void | semmle.label | s [post update] [m1] : void |
| aliasing.cpp:79:11:79:20 | call to user_input : void | semmle.label | call to user_input : void |
| aliasing.cpp:80:10:80:10 | s [m1] : void | semmle.label | s [m1] : void |
| aliasing.cpp:80:12:80:13 | m1 | semmle.label | m1 |
| aliasing.cpp:86:3:86:21 | (reference dereference) [post update] : void | semmle.label | (reference dereference) [post update] : void |
| aliasing.cpp:86:3:86:21 | (reference dereference) [post update] [m1] : void | semmle.label | (reference dereference) [post update] [m1] : void |
| aliasing.cpp:86:10:86:19 | call to user_input : void | semmle.label | call to user_input : void |
| aliasing.cpp:87:10:87:10 | s [m1] : void | semmle.label | s [m1] : void |
| aliasing.cpp:87:12:87:13 | m1 | semmle.label | m1 |
| aliasing.cpp:92:3:92:23 | s [post update] : void | semmle.label | s [post update] : void |
| aliasing.cpp:92:3:92:23 | s [post update] [m1] : void | semmle.label | s [post update] [m1] : void |
| aliasing.cpp:92:12:92:21 | call to user_input : void | semmle.label | call to user_input : void |
| aliasing.cpp:93:10:93:10 | s [m1] : void | semmle.label | s [m1] : void |
| aliasing.cpp:93:12:93:13 | m1 | semmle.label | m1 |
| struct_init.c:20:20:20:29 | VariableAddress [post update] : void | semmle.label | VariableAddress [post update] : void |
| struct_init.c:20:20:20:29 | VariableAddress [post update] [a] : void | semmle.label | VariableAddress [post update] [a] : void |
| struct_init.c:20:20:20:29 | call to user_input : void | semmle.label | call to user_input : void |
| struct_init.c:22:8:22:9 | ab [a] : void | semmle.label | ab [a] : void |
| struct_init.c:22:11:22:11 | a | semmle.label | a |
| struct_init.c:27:7:27:16 | FieldAddress [post update] : void | semmle.label | FieldAddress [post update] : void |
| struct_init.c:27:7:27:16 | FieldAddress [post update] [a] : void | semmle.label | FieldAddress [post update] [a] : void |
| struct_init.c:27:7:27:16 | call to user_input : void | semmle.label | call to user_input : void |
| struct_init.c:31:14:31:21 | nestedAB [a] : void | semmle.label | nestedAB [a] : void |
| struct_init.c:31:23:31:23 | a | semmle.label | a |
#select
| A.cpp:132:10:132:13 | (void *)... | A.cpp:126:12:126:18 | new : void | A.cpp:132:10:132:13 | (void *)... | (void *)... flows from $@ | A.cpp:126:12:126:18 | new : void | new : void |