C++: Fix for field content indirection (1-based).

This commit is contained in:
Geoffrey White
2024-03-19 17:45:58 +00:00
parent 73e95d67b9
commit b598b4ac45
4 changed files with 41 additions and 14 deletions

View File

@@ -39,7 +39,8 @@ module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
string encodeContent(ContentSet cs, string arg) {
exists(FieldContent c |
cs.isSingleton(c) and
result = indirectionString(c.getIndirectionIndex()) + "Field" and
// FieldContent indices have 0 for the address, 1 for content, so we need to subtract one.
result = indirectionString(c.getIndirectionIndex() - 1) + "Field" and
arg = c.getField().getName()
)
}
@@ -87,7 +88,8 @@ module Input implements InputSig<DataFlowImplSpecific::CppDataFlow> {
// field content (with indirection support).
exists(FieldContent c |
result.isSingleton(c) and
token = indirectionString(c.getIndirectionIndex()) + c.getField().getName()
// FieldContent indices have 0 for the address, 1 for content, so we need to subtract one.
token = indirectionString(c.getIndirectionIndex() - 1) + c.getField().getName()
)
}
}

View File

@@ -2317,6 +2317,8 @@ private Field getAFieldWithSize(Union u, int bytes) {
cached
private newtype TContent =
TFieldContent(Field f, int indirectionIndex) {
// the indirection index for field content starts at 1 (because `TFieldContent` is thought of as
// the address of the field, `FieldAddress` in the IR).
indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(f.getUnspecifiedType())] and
// Reads and writes of union fields are tracked using `UnionContent`.
not f.getDeclaringType() instanceof Union
@@ -2326,7 +2328,8 @@ private newtype TContent =
f = u.getAField() and
bytes = getFieldSize(f) and
// We key `UnionContent` by the union instead of its fields since a write to one
// field can be read by any read of the union's fields.
// field can be read by any read of the union's fields. Again, the indirection index
// is 1-based (because 0 is considered the address).
indirectionIndex =
[1 .. max(Ssa::getMaxIndirectionsForType(getAFieldWithSize(u, bytes).getUnspecifiedType()))]
)

View File

@@ -16,9 +16,18 @@
| tests.cpp:136:6:136:34 | [summary param] 0 indirection in madArg0IndirectToArg1Indirect | ParameterNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
| tests.cpp:136:6:136:34 | [summary param] 1 indirection in madArg0IndirectToArg1Indirect | ParameterNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
| tests.cpp:136:6:136:34 | [summary] to write: Argument[1 indirection] in madArg0IndirectToArg1Indirect | PostUpdateNode | madArg0IndirectToArg1Indirect | madArg0IndirectToArg1Indirect |
| tests.cpp:140:5:140:32 | [summary param] 0 in madArg0FieldIndirectToReturn | ParameterNode | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
| tests.cpp:140:5:140:32 | [summary] read: Argument[0].*Field[value] in madArg0FieldIndirectToReturn | | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
| tests.cpp:140:5:140:32 | [summary] to write: ReturnValue in madArg0FieldIndirectToReturn | ReturnNode | madArg0FieldIndirectToReturn | madArg0FieldIndirectToReturn |
| tests.cpp:138:5:138:24 | [summary param] 0 in madArg0FieldToReturn | ParameterNode | madArg0FieldToReturn | madArg0FieldToReturn |
| tests.cpp:138:5:138:24 | [summary] read: Argument[0].Field[value] in madArg0FieldToReturn | | madArg0FieldToReturn | madArg0FieldToReturn |
| tests.cpp:138:5:138:24 | [summary] to write: ReturnValue in madArg0FieldToReturn | ReturnNode | madArg0FieldToReturn | madArg0FieldToReturn |
| tests.cpp:139:5:139:32 | [summary param] 0 indirection in madArg0IndirectFieldToReturn | ParameterNode | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
| tests.cpp:139:5:139:32 | [summary] read: Argument[0 indirection].Field[value] in madArg0IndirectFieldToReturn | | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
| tests.cpp:139:5:139:32 | [summary] to write: ReturnValue in madArg0IndirectFieldToReturn | ReturnNode | madArg0IndirectFieldToReturn | madArg0IndirectFieldToReturn |
| tests.cpp:141:13:141:32 | [summary param] 0 in madArg0ToReturnField | ParameterNode | madArg0ToReturnField | madArg0ToReturnField |
| tests.cpp:141:13:141:32 | [summary] to write: ReturnValue in madArg0ToReturnField | ReturnNode | madArg0ToReturnField | madArg0ToReturnField |
| tests.cpp:141:13:141:32 | [summary] to write: ReturnValue.Field[value] in madArg0ToReturnField | | madArg0ToReturnField | madArg0ToReturnField |
| tests.cpp:142:14:142:41 | [summary param] 0 in madArg0ToReturnIndirectField | ParameterNode | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
| tests.cpp:142:14:142:41 | [summary] to write: *ReturnValue in madArg0ToReturnIndirectField | ReturnNode | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
| tests.cpp:142:14:142:41 | [summary] to write: *ReturnValue.Field[value] in madArg0ToReturnIndirectField | | madArg0ToReturnIndirectField | madArg0ToReturnIndirectField |
| tests.cpp:143:13:143:40 | [summary param] 0 in madArg0ToReturnFieldIndirect | ParameterNode | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
| tests.cpp:143:13:143:40 | [summary] to write: ReturnValue in madArg0ToReturnFieldIndirect | ReturnNode | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
| tests.cpp:143:13:143:40 | [summary] to write: ReturnValue.*Field[ptr] in madArg0ToReturnFieldIndirect | | madArg0ToReturnFieldIndirect | madArg0ToReturnFieldIndirect |
@@ -27,6 +36,13 @@
| tests.cpp:227:7:227:19 | [summary] to write: Argument[this indirection] in madArg0ToSelf | PostUpdateNode | madArg0ToSelf | madArg0ToSelf |
| tests.cpp:228:6:228:20 | [summary param] this indirection in madSelfToReturn | ParameterNode | madSelfToReturn | madSelfToReturn |
| tests.cpp:228:6:228:20 | [summary] to write: ReturnValue in madSelfToReturn | ReturnNode | madSelfToReturn | madSelfToReturn |
| tests.cpp:230:7:230:20 | [summary param] 0 in madArg0ToField | ParameterNode | madArg0ToField | madArg0ToField |
| tests.cpp:230:7:230:20 | [summary param] this indirection in madArg0ToField | ParameterNode | madArg0ToField | madArg0ToField |
| tests.cpp:230:7:230:20 | [summary] to write: Argument[this indirection] in madArg0ToField | PostUpdateNode | madArg0ToField | madArg0ToField |
| tests.cpp:230:7:230:20 | [summary] to write: Argument[this indirection].Field[val] in madArg0ToField | | madArg0ToField | madArg0ToField |
| tests.cpp:231:6:231:21 | [summary param] this indirection in madFieldToReturn | ParameterNode | madFieldToReturn | madFieldToReturn |
| tests.cpp:231:6:231:21 | [summary] read: Argument[this indirection].Field[val] in madFieldToReturn | | madFieldToReturn | madFieldToReturn |
| tests.cpp:231:6:231:21 | [summary] to write: ReturnValue in madFieldToReturn | ReturnNode | madFieldToReturn | madFieldToReturn |
| tests.cpp:256:7:256:30 | [summary param] this indirection in namespaceMadSelfToReturn | ParameterNode | namespaceMadSelfToReturn | namespaceMadSelfToReturn |
| tests.cpp:256:7:256:30 | [summary] to write: ReturnValue in namespaceMadSelfToReturn | ReturnNode | namespaceMadSelfToReturn | namespaceMadSelfToReturn |
| tests.cpp:377:5:377:29 | [summary param] 0 in madCallArg0ReturnToReturn | ParameterNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
@@ -34,6 +50,12 @@
| tests.cpp:377:5:377:29 | [summary] read: Argument[0].ReturnValue in madCallArg0ReturnToReturn | OutNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
| tests.cpp:377:5:377:29 | [summary] to write: Argument[0].Parameter[this] in madCallArg0ReturnToReturn | ArgumentNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
| tests.cpp:377:5:377:29 | [summary] to write: ReturnValue in madCallArg0ReturnToReturn | ReturnNode | madCallArg0ReturnToReturn | madCallArg0ReturnToReturn |
| tests.cpp:378:9:378:38 | [summary param] 0 in madCallArg0ReturnToReturnFirst | ParameterNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:378:9:378:38 | [summary] read: Argument[0].Parameter[this] in madCallArg0ReturnToReturnFirst | PostUpdateNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:378:9:378:38 | [summary] read: Argument[0].ReturnValue in madCallArg0ReturnToReturnFirst | OutNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:378:9:378:38 | [summary] to write: Argument[0].Parameter[this] in madCallArg0ReturnToReturnFirst | ArgumentNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:378:9:378:38 | [summary] to write: ReturnValue in madCallArg0ReturnToReturnFirst | ReturnNode | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:378:9:378:38 | [summary] to write: ReturnValue.Field[first] in madCallArg0ReturnToReturnFirst | | madCallArg0ReturnToReturnFirst | madCallArg0ReturnToReturnFirst |
| tests.cpp:379:6:379:25 | [summary param] 0 in madCallArg0WithValue | ParameterNode | madCallArg0WithValue | madCallArg0WithValue |
| tests.cpp:379:6:379:25 | [summary param] 1 in madCallArg0WithValue | ParameterNode | madCallArg0WithValue | madCallArg0WithValue |
| tests.cpp:379:6:379:25 | [summary] read: Argument[0].Parameter[0] in madCallArg0WithValue | PostUpdateNode | madCallArg0WithValue | madCallArg0WithValue |

View File

@@ -183,15 +183,15 @@ void test_summaries() {
e = source();
mc2.value = source();
mc2.ptr = &e;
sink(madArg0FieldToReturn(mc2)); // $ MISSING: ir
sink(madArg0IndirectFieldToReturn(&mc2)); // $ MISSING: ir
sink(madArg0FieldIndirectToReturn(mc2)); // $ ir
sink(madArg0FieldToReturn(mc2)); // $ ir
sink(madArg0IndirectFieldToReturn(&mc2)); // $ ir
sink(madArg0FieldIndirectToReturn(mc2)); // $ MISSING: ir
sink(madArg0ToReturnField(0).value);
sink(madArg0ToReturnField(source()).value); // $ MISSING: ir
sink(madArg0ToReturnField(source()).value); // $ ir
MyContainer *rtn1 = madArg0ToReturnIndirectField(source());
sink(rtn1->value); // $ MISSING: ir
sink(rtn1->value); // $ ir
MyContainer rtn2 = madArg0ToReturnFieldIndirect(source());
int *rtn2_ptr = rtn2.ptr;
@@ -310,7 +310,7 @@ void test_class_members() {
sink(*ptr); // $ ir
mc3.madArg0ToField(source());
sink(mc3.val); // $ MISSING: ir
sink(mc3.val); // $ ir
mc4 = source2();
mc4_ptr = &mc4;
@@ -323,7 +323,7 @@ void test_class_members() {
sink(source2().notASummary());
mc5.val = source();
sink(mc5.madFieldToReturn()); // $ MISSING: ir
sink(mc5.madFieldToReturn()); // $ ir
mnc2 = source3();
mnc2_ptr = &mnc2;
@@ -339,7 +339,7 @@ void test_class_members() {
sink(mc6.madSelfToReturn()); // $ ir
mc7.madArg0ToField(source());
sink(mc7.madFieldToReturn()); // $ MISSING: ir
sink(mc7.madFieldToReturn()); // $ ir
// test taint involving qualifier