C++: Make Argument[-1] refer to *this rather than this.

This commit is contained in:
Geoffrey White
2024-03-12 17:06:52 +00:00
parent 22d5e9bbfb
commit cbacd51337
4 changed files with 26 additions and 17 deletions

View File

@@ -36,7 +36,8 @@
* "Argument[n]", "Argument[n1..n2]", "ReturnValue":
* - "": Selects a write to the selected element in case this is a field.
* - "Argument[n]": Selects an argument in a call to the selected element.
* The arguments are zero-indexed, and `-1` specifies the qualifier.
* The arguments are zero-indexed, and `-1` specifies the qualifier object,
* that is, `*this`.
* - "Argument[n1..n2]": Similar to "Argument[n]" but select any argument in
* the given range. The range is inclusive at both ends.
* - "ReturnValue": Selects a value being returned by the selected element.
@@ -47,14 +48,16 @@
* - "": Selects a read of a selected field, or a selected parameter.
* - "Argument[n]": Selects the post-update value of an argument in a call to the
* selected element. That is, the value of the argument after the call returns.
* The arguments are zero-indexed, and `-1` specifies the qualifier.
* The arguments are zero-indexed, and `-1` specifies the qualifier object,
* that is, `*this`.
* - "Argument[n1..n2]": Similar to "Argument[n]" but select any argument in
* the given range. The range is inclusive at both ends.
* - "Parameter": Selects the value of a parameter of the selected element.
* "Parameter" is also allowed in case the selected element is already a
* parameter itself.
* - "Parameter[n]": Similar to "Parameter" but restricted to a specific
* numbered parameter (zero-indexed, and `-1` specifies the value of `this`).
* numbered parameter. The parameters are zero-indexed, and `-1` specifies
* the qualifier object, that is, `*this`.
* - "Parameter[n1..n2]": Similar to "Parameter[n]" but selects any parameter
* in the given range. The range is inclusive at both ends.
* - "ReturnValue": Selects the return value of a call to the selected element.

View File

@@ -48,7 +48,10 @@ module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
// needed to support `Argument[x..y]` ranges and `Argument[-1]`
token.getName() = "Argument" and
exists(int pos | pos = AccessPath::parseInt(token.getAnArgument()) |
result = TDirectPosition(pos)
pos >= 0 and result = TDirectPosition(pos)
or
// `Argument[-1]` is the qualifier object `*this`, not the `this` pointer itself
pos = -1 and result = TIndirectionPosition(pos, 1)
)
}
@@ -57,7 +60,10 @@ module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
// needed to support `Parameter[x..y]` ranges and `Parameter[-1]`
token.getName() = "Parameter" and
exists(int pos | pos = AccessPath::parseInt(token.getAnArgument()) |
result = TDirectPosition(pos)
pos >= 0 and result = TDirectPosition(pos)
or
// `Argument[-1]` is the qualifier object `*this`, not the `this` pointer itself
pos = -1 and result = TIndirectionPosition(pos, 1)
)
}
}

View File

@@ -6,11 +6,11 @@
| tests.cpp:119:6:119:18 | [summary param] 1 in madArg0ToArg1 | ParameterNode | madArg0ToArg1 | madArg0ToArg1 |
| tests.cpp:119:6:119:18 | [summary] to write: Argument[1] in madArg0ToArg1 | PostUpdateNode | madArg0ToArg1 | madArg0ToArg1 |
| tests.cpp:180:7:180:19 | [summary param] 0 in madArg0ToSelf | ParameterNode | madArg0ToSelf | madArg0ToSelf |
| tests.cpp:180:7:180:19 | [summary param] this in madArg0ToSelf | ParameterNode | madArg0ToSelf | madArg0ToSelf |
| tests.cpp:180:7:180:19 | [summary] to write: Argument[this] in madArg0ToSelf | PostUpdateNode | madArg0ToSelf | madArg0ToSelf |
| tests.cpp:181:6:181:20 | [summary param] this in madSelfToReturn | ParameterNode | madSelfToReturn | madSelfToReturn |
| tests.cpp:180:7:180:19 | [summary param] this indirection in madArg0ToSelf | ParameterNode | madArg0ToSelf | madArg0ToSelf |
| tests.cpp:180:7:180:19 | [summary] to write: Argument[this indirection] in madArg0ToSelf | PostUpdateNode | madArg0ToSelf | madArg0ToSelf |
| tests.cpp:181:6:181:20 | [summary param] this indirection in madSelfToReturn | ParameterNode | madSelfToReturn | madSelfToReturn |
| tests.cpp:181:6:181:20 | [summary] to write: ReturnValue in madSelfToReturn | ReturnNode | madSelfToReturn | madSelfToReturn |
| tests.cpp:209:7:209:30 | [summary param] this in namespaceMadSelfToReturn | ParameterNode | namespaceMadSelfToReturn | namespaceMadSelfToReturn |
| tests.cpp:209:7:209:30 | [summary param] this indirection in namespaceMadSelfToReturn | ParameterNode | namespaceMadSelfToReturn | namespaceMadSelfToReturn |
| tests.cpp:209:7:209:30 | [summary] to write: ReturnValue in namespaceMadSelfToReturn | ReturnNode | namespaceMadSelfToReturn | namespaceMadSelfToReturn |
| tests.cpp:305:5:305:29 | [summary param] 0 in madCallArg0ReturnToReturn | ParameterNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
| tests.cpp:305:5:305:29 | [summary] read: Argument[0].Parameter[this] in madCallArg0ReturnToReturn | PostUpdateNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |

View File

@@ -253,7 +253,7 @@ void test_class_members() {
mc2.madArg0ToSelf(0);
sink(mc2);
mc2.madArg0ToSelf(source());
sink(mc2); // $ MISSING: ir
sink(mc2); // $ ir
ptr = new MyClass();
sink(*ptr);
@@ -268,11 +268,11 @@ void test_class_members() {
mc4 = source2();
mc4_ptr = &mc4;
sink(mc4); // $ ir
sink(mc4.madSelfToReturn()); // $ MISSING: ir
sink(mc4.madSelfToReturn()); // $ ir
sink(mc4.notASummary());
sink(mc4_ptr->madSelfToReturn()); // $ MISSING: ir
sink(mc4_ptr->madSelfToReturn()); // $ ir
sink(mc4_ptr->notASummary());
sink(source2().madSelfToReturn()); // $ ir
sink(source2().madSelfToReturn()); // $ MISSING: ir (works if flow is modelled from qualifier *address*)
sink(source2().notASummary());
mc5.val = source();
@@ -280,16 +280,16 @@ void test_class_members() {
mnc2 = source3();
mnc2_ptr = &mnc2;
sink(mnc2.namespaceMadSelfToReturn()); // $ MISSING: ir
sink(mnc2_ptr->namespaceMadSelfToReturn()); // $ MISSING: ir
sink(source3().namespaceMadSelfToReturn()); // $ ir
sink(mnc2.namespaceMadSelfToReturn()); // $ ir
sink(mnc2_ptr->namespaceMadSelfToReturn()); // $ ir
sink(source3().namespaceMadSelfToReturn()); // $ MISSING: ir (works if flow is modelled from qualifier *address*)
// test class member sources + sinks + summaries together
mc.memberMadSinkArg0(mc.memberRemoteMadSource()); // $ ir
mc6.madArg0ToSelf(source());
sink(mc6.madSelfToReturn()); // $ MISSING: ir
sink(mc6.madSelfToReturn()); // $ ir
mc7.madArg0ToField(source());
sink(mc7.madFieldToReturn()); // $ MISSING: ir