diff --git a/c/cert/src/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.ql b/c/cert/src/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.ql index 31618785d2..0f85dabd0b 100644 --- a/c/cert/src/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.ql +++ b/c/cert/src/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.ql @@ -16,7 +16,7 @@ */ import cpp -import semmle.code.cpp.dataflow.DataFlow +import semmle.code.cpp.dataflow.new.DataFlow import semmle.code.cpp.controlflow.Dominance import codingstandards.c.cert import codingstandards.cpp.Variable diff --git a/c/cert/test/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.expected b/c/cert/test/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.expected index 40009edc03..e5ced8c5aa 100644 --- a/c/cert/test/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.expected +++ b/c/cert/test/rules/EXP43-C/RestrictPointerReferencesOverlappingObject.expected @@ -1,16 +1,12 @@ -WARNING: module 'DataFlow' has been deprecated and may be removed in future (RestrictPointerReferencesOverlappingObject.ql:47,57-65) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (RestrictPointerReferencesOverlappingObject.ql:48,22-30) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (RestrictPointerReferencesOverlappingObject.ql:52,20-28) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (RestrictPointerReferencesOverlappingObject.ql:58,3-11) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (RestrictPointerReferencesOverlappingObject.ql:61,58-66) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (RestrictPointerReferencesOverlappingObject.ql:77,64-72) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (RestrictPointerReferencesOverlappingObject.ql:78,64-72) -| test.c:18:22:18:23 | i2 | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:18:17:18:18 | i3 | i3 | test.c:18:22:18:23 | i2 | the object pointed to by i2 | -| test.c:19:8:19:9 | g2 | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:5:15:5:16 | g1 | g1 | test.c:19:8:19:9 | g2 | the object pointed to by g2 | -| test.c:20:8:20:9 | i2 | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:16:17:16:18 | i1 | i1 | test.c:20:8:20:9 | i2 | the object pointed to by i2 | -| test.c:27:10:27:11 | g1 | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:23:19:23:20 | i5 | i5 | test.c:19:8:19:9 | g2 | the same source value | -| test.c:28:10:28:11 | g1 | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:22:19:22:20 | i4 | i4 | test.c:19:8:19:9 | g2 | the same source value | -| test.c:39:22:39:26 | & ... | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:39:17:39:18 | px | px | test.c:38:28:38:30 | & ... | v1 via address-of | -| test.c:45:10:45:14 | & ... | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:42:19:42:20 | pz | pz | test.c:43:10:43:14 | & ... | v1 via address-of | -| test.c:46:10:46:14 | & ... | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:41:19:41:20 | py | py | test.c:43:10:43:14 | & ... | v1 via address-of | -| test.c:46:10:46:14 | & ... | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:41:19:41:20 | py | py | test.c:45:10:45:14 | & ... | v1 via address-of | +| test.c:15:22:15:23 | i2 | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:15:17:15:18 | i3 | i3 | test.c:15:22:15:23 | i2 | the object pointed to by i2 | +| test.c:34:22:34:23 | g4 | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:34:17:34:18 | i2 | i2 | test.c:34:22:34:23 | g4 | the same source value | +| test.c:35:8:35:9 | g4 | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:18:15:18:16 | g3 | g3 | test.c:35:8:35:9 | g4 | the object pointed to by g4 | +| test.c:49:10:49:11 | g5 | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:45:19:45:20 | i5 | i5 | test.c:41:22:41:23 | g5 | the same source value | +| test.c:49:10:49:11 | g5 | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:45:19:45:20 | i5 | i5 | test.c:47:10:47:11 | g5 | the same source value | +| test.c:50:10:50:11 | g5 | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:44:19:44:20 | i4 | i4 | test.c:41:22:41:23 | g5 | the same source value | +| test.c:50:10:50:11 | g5 | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:44:19:44:20 | i4 | i4 | test.c:47:10:47:11 | g5 | the same source value | +| test.c:50:10:50:11 | g5 | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:44:19:44:20 | i4 | i4 | test.c:49:10:49:11 | g5 | the same source value | +| test.c:63:22:63:26 | & ... | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:63:17:63:18 | px | px | test.c:62:28:62:30 | & ... | v1 via address-of | +| test.c:69:10:69:14 | & ... | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:66:19:66:20 | pz | pz | test.c:67:10:67:14 | & ... | v1 via address-of | +| test.c:70:10:70:14 | & ... | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:65:19:65:20 | py | py | test.c:67:10:67:14 | & ... | v1 via address-of | +| test.c:70:10:70:14 | & ... | Assignment to restrict-qualified pointer $@ results in pointers aliasing $@. | test.c:65:19:65:20 | py | py | test.c:69:10:69:14 | & ... | v1 via address-of | diff --git a/c/cert/test/rules/EXP43-C/test.c b/c/cert/test/rules/EXP43-C/test.c index 3bf7cfa490..1a62fdc6ef 100644 --- a/c/cert/test/rules/EXP43-C/test.c +++ b/c/cert/test/rules/EXP43-C/test.c @@ -2,35 +2,59 @@ #include #include -int *restrict g1; -int *restrict g2; -int *restrict g1_1; -int *g2_1; - struct s1 { int x, y, z; }; struct s1 v1; -void test_global_local() { +int *restrict g1; +int *restrict g2; +void test_global_local_1() { int *restrict i1 = g1; // COMPLIANT int *restrict i2 = g2; // COMPLIANT int *restrict i3 = i2; // NON_COMPLIANT - g1 = g2; // NON_COMPLIANT - i1 = i2; // NON_COMPLIANT +} + +int *restrict g3; +int *restrict g4; +void test_global_local_2() { + // The second assignment in this block is non-compliant for subtle reasons. + // + // If we assume that `test_global_local_2` is only called once, then `g3` and + // `g4` will likely point to different values and therefore `i1` and `i2` do + // not alias each other. from g3 to g4 is too late to cause an issue. This was + // how this query worked under the old dataflow library. + // + // However, if we assume this function is called more than once, then the + // assignment that causes `g3` and `g4` to have the same value, at the end of + // this function, can predate the assignments that initialize `i1` and `i2` + // within this function, leading to aliasing that violates the rule. This is + // how the new dataflow library handles this case. + int *restrict i1 = g3; // COMPLIANT + int *restrict i2 = g4; // NON_COMPLIANT + g3 = g4; // NON_COMPLIANT +} + +int *restrict g5; +int *restrict g6; +void test_global_local_3() { + int *restrict i2 = g5; // COMPLIANT + int *restrict i3 = g6; // COMPLIANT { int *restrict i4; int *restrict i5; int *restrict i6; - i4 = g1; // COMPLIANT + i4 = g5; // COMPLIANT -- first assignment within this block i4 = (void *)0; // COMPLIANT - i5 = g1; // NON_COMPLIANT - block rather than statement scope matters - i4 = g1; // NON_COMPLIANT - i6 = g2; // COMPLIANT + i5 = g5; // NON_COMPLIANT - block rather than statement scope matters + i4 = g5; // NON_COMPLIANT + i6 = g6; // COMPLIANT -- first assignment within this block } } -void test_global_local_1() { +int *restrict g1_1; +int *g2_1; +void test_global_local_4() { g1_1 = g2_1; // COMPLIANT } diff --git a/change_notes/2026-10-01-use-new-dataflow-in-exp43-c.md b/change_notes/2026-10-01-use-new-dataflow-in-exp43-c.md new file mode 100644 index 0000000000..e4d2c198b7 --- /dev/null +++ b/change_notes/2026-10-01-use-new-dataflow-in-exp43-c.md @@ -0,0 +1,2 @@ + - `EXP43-C` - `RestrictPointerReferencesOverlappingObject.ql`: + - Updated to use the new dataflow library for tracking assignments to restrict-qualified pointers. Using the new dataflow library may introduce a different set of false positives and false negatives compared to the previous implementation, though it has higher precision overall. \ No newline at end of file