diff --git a/c/cert/src/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.ql b/c/cert/src/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.ql index 856cad1d58..23e3a94de7 100644 --- a/c/cert/src/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.ql +++ b/c/cert/src/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.ql @@ -18,7 +18,7 @@ import cpp import codingstandards.c.cert -import semmle.code.cpp.dataflow.DataFlow +import semmle.code.cpp.dataflow.new.DataFlow import semmle.code.cpp.controlflow.Dominance import IndirectCastFlow::PathGraph @@ -35,12 +35,12 @@ class MemsetFunction extends Function { } } -class IndirectCastAnalysisUnconvertedCastExpr extends Expr { - IndirectCastAnalysisUnconvertedCastExpr() { this = any(Cast c).getUnconverted() } +class CastedExpr extends Expr { + CastedExpr() { this = any(Cast c).getExpr() } } -class IndirectCastAnalysisDereferenceSink extends Expr { - IndirectCastAnalysisDereferenceSink() { dereferenced(this) } +class DereferencedExpr extends Expr { + DereferencedExpr() { dereferenced(this) } } class ReallocationFunction extends AllocationFunction { @@ -68,14 +68,14 @@ module IndirectCastConfig implements DataFlow::StateConfigSig { predicate isSource(DataFlow::Node source, FlowState state) { state instanceof IndirectCastDefaultFlowState and - source.asExpr() instanceof IndirectCastAnalysisUnconvertedCastExpr + source.asExpr() instanceof CastedExpr } predicate isSink(DataFlow::Node sink, FlowState state) { - sink.asExpr() instanceof IndirectCastAnalysisUnconvertedCastExpr and + sink.asExpr() instanceof CastedExpr and state instanceof IndirectCastDefaultFlowState or - sink.asExpr() instanceof IndirectCastAnalysisDereferenceSink and + sink.asExpr() instanceof DereferencedExpr and state instanceof IndirectCastReallocatedFlowState and // The memset call won't always have an edge to subsequent dereferences. // @@ -193,17 +193,18 @@ Type compatibleTypes(Type type) { } from - IndirectCastFlow::PathNode source, IndirectCastFlow::PathNode sink, Cast cast, Type fromType, - Type toType + Expr sinkExpr, IndirectCastFlow::PathNode source, IndirectCastFlow::PathNode sink, Cast cast, + Type fromType, Type toType where - not isExcluded(sink.getNode().asExpr(), - Pointers3Package::doNotAccessVariableViaPointerOfIncompatibleTypeQuery()) and + not isExcluded(sinkExpr, Pointers3Package::doNotAccessVariableViaPointerOfIncompatibleTypeQuery()) and cast.getFile().compiledAsC() and IndirectCastFlow::flowPath(source, sink) and // include only sinks which are not a compatible type to the associated source source.getNode().asExpr() = cast.getUnconverted() and fromType = cast.getUnconverted().getType().(PointerType).getBaseType() and toType = sink.getNode().asExpr().getActualType().(PointerType).getBaseType() and - not toType = compatibleTypes(fromType) -select sink.getNode().asExpr().getUnconverted(), source, sink, + not toType = compatibleTypes(fromType) and + sinkExpr = sink.getNode().asExpr() and + (sinkExpr instanceof CastedExpr or sinkExpr instanceof DereferencedExpr) +select sinkExpr, source, sink, "Cast from " + fromType + " to " + toType + " results in an incompatible pointer base type." diff --git a/c/cert/test/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.expected b/c/cert/test/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.expected index 381e409d2a..3f16fe6eb7 100644 --- a/c/cert/test/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.expected +++ b/c/cert/test/rules/EXP39-C/DoNotAccessVariableViaPointerOfIncompatibleType.expected @@ -1,67 +1,69 @@ -WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAccessVariableViaPointerOfIncompatibleType.ql:66,38-46) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAccessVariableViaPointerOfIncompatibleType.ql:69,22-30) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAccessVariableViaPointerOfIncompatibleType.ql:74,20-28) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAccessVariableViaPointerOfIncompatibleType.ql:107,23-31) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAccessVariableViaPointerOfIncompatibleType.ql:116,5-13) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAccessVariableViaPointerOfIncompatibleType.ql:116,45-53) -WARNING: module 'DataFlow' has been deprecated and may be removed in future (DoNotAccessVariableViaPointerOfIncompatibleType.ql:138,27-35) edges -| test.c:49:8:49:9 | s3 | test.c:50:8:50:9 | s1 | provenance | | +| test.c:49:3:49:9 | ... = ... | test.c:50:8:50:9 | s1 | provenance | | +| test.c:49:8:49:9 | s3 | test.c:49:3:49:9 | ... = ... | provenance | | +| test.c:60:16:60:18 | E1A | test.c:60:16:60:18 | E1A | provenance | | | test.c:60:16:60:18 | E1A | test.c:61:16:61:17 | e1 | provenance | | -| test.c:60:16:60:18 | E1A | test.c:65:10:65:12 | & ... | provenance | | -| test.c:68:22:68:22 | v | test.c:68:41:68:41 | v | provenance | | +| test.c:68:22:68:22 | v | test.c:68:34:68:41 | v | provenance | | | test.c:72:13:72:15 | & ... | test.c:68:22:68:22 | v | provenance | | | test.c:74:13:74:15 | & ... | test.c:68:22:68:22 | v | provenance | | -| test.c:97:32:97:37 | call to malloc | test.c:98:40:98:41 | s2 | provenance | | -| test.c:97:32:97:37 | call to malloc | test.c:98:40:98:41 | s2 | provenance | | -| test.c:98:32:98:38 | call to realloc | test.c:99:3:99:4 | s3 | provenance | | -| test.c:98:32:98:38 | call to realloc | test.c:100:10:100:11 | s3 | provenance | | -| test.c:98:40:98:41 | s2 | test.c:98:32:98:38 | call to realloc | provenance | Config | +| test.c:97:19:97:56 | call to malloc | test.c:97:19:97:56 | call to malloc | provenance | | +| test.c:97:19:97:56 | call to malloc | test.c:98:40:98:41 | s2 | provenance | | +| test.c:97:19:97:56 | call to malloc | test.c:98:40:98:41 | s2 | provenance | | +| test.c:98:19:98:61 | call to realloc | test.c:98:19:98:61 | call to realloc | provenance | | +| test.c:98:19:98:61 | call to realloc | test.c:98:19:98:61 | call to realloc | provenance | | +| test.c:98:19:98:61 | call to realloc | test.c:99:3:99:4 | s3 | provenance | | +| test.c:98:19:98:61 | call to realloc | test.c:100:10:100:11 | s3 | provenance | | +| test.c:98:40:98:41 | s2 | test.c:98:19:98:61 | call to realloc | provenance | Config | nodes -| test.c:6:19:6:20 | & ... | semmle.label | & ... | -| test.c:11:10:11:11 | & ... | semmle.label | & ... | -| test.c:13:17:13:19 | & ... | semmle.label | & ... | -| test.c:15:17:15:19 | & ... | semmle.label | & ... | -| test.c:19:18:19:20 | & ... | semmle.label | & ... | -| test.c:20:20:20:22 | & ... | semmle.label | & ... | -| test.c:22:11:22:13 | & ... | semmle.label | & ... | -| test.c:27:17:27:19 | & ... | semmle.label | & ... | -| test.c:28:10:28:12 | & ... | semmle.label | & ... | -| test.c:29:13:29:15 | & ... | semmle.label | & ... | -| test.c:30:19:30:21 | & ... | semmle.label | & ... | -| test.c:31:16:31:18 | & ... | semmle.label | & ... | +| test.c:6:12:6:20 | & ... | semmle.label | & ... | +| test.c:11:3:11:11 | & ... | semmle.label | & ... | +| test.c:13:3:13:19 | & ... | semmle.label | & ... | +| test.c:15:3:15:19 | & ... | semmle.label | & ... | +| test.c:19:3:19:20 | & ... | semmle.label | & ... | +| test.c:20:3:20:22 | & ... | semmle.label | & ... | +| test.c:22:3:22:13 | & ... | semmle.label | & ... | +| test.c:27:3:27:19 | & ... | semmle.label | & ... | +| test.c:28:3:28:12 | & ... | semmle.label | & ... | +| test.c:29:3:29:15 | & ... | semmle.label | & ... | +| test.c:30:3:30:21 | & ... | semmle.label | & ... | +| test.c:31:3:31:18 | & ... | semmle.label | & ... | | test.c:47:8:47:9 | s2 | semmle.label | s2 | +| test.c:49:3:49:9 | ... = ... | semmle.label | ... = ... | | test.c:49:8:49:9 | s3 | semmle.label | s3 | | test.c:49:8:49:9 | s3 | semmle.label | s3 | | test.c:50:8:50:9 | s1 | semmle.label | s1 | | test.c:60:16:60:18 | E1A | semmle.label | E1A | | test.c:60:16:60:18 | E1A | semmle.label | E1A | +| test.c:60:16:60:18 | E1A | semmle.label | E1A | | test.c:61:16:61:17 | e1 | semmle.label | e1 | -| test.c:65:10:65:12 | & ... | semmle.label | & ... | +| test.c:65:3:65:12 | & ... | semmle.label | & ... | | test.c:68:22:68:22 | v | semmle.label | v | -| test.c:68:41:68:41 | v | semmle.label | v | +| test.c:68:34:68:41 | v | semmle.label | v | | test.c:72:13:72:15 | & ... | semmle.label | & ... | | test.c:72:13:72:15 | & ... | semmle.label | & ... | | test.c:74:13:74:15 | & ... | semmle.label | & ... | | test.c:74:13:74:15 | & ... | semmle.label | & ... | -| test.c:97:32:97:37 | call to malloc | semmle.label | call to malloc | -| test.c:97:32:97:37 | call to malloc | semmle.label | call to malloc | -| test.c:98:32:98:38 | call to realloc | semmle.label | call to realloc | -| test.c:98:32:98:38 | call to realloc | semmle.label | call to realloc | -| test.c:98:32:98:38 | call to realloc | semmle.label | call to realloc | +| test.c:97:19:97:56 | call to malloc | semmle.label | call to malloc | +| test.c:97:19:97:56 | call to malloc | semmle.label | call to malloc | +| test.c:97:19:97:56 | call to malloc | semmle.label | call to malloc | +| test.c:98:19:98:61 | call to realloc | semmle.label | call to realloc | +| test.c:98:19:98:61 | call to realloc | semmle.label | call to realloc | +| test.c:98:19:98:61 | call to realloc | semmle.label | call to realloc | +| test.c:98:19:98:61 | call to realloc | semmle.label | call to realloc | +| test.c:98:19:98:61 | call to realloc | semmle.label | call to realloc | | test.c:98:40:98:41 | s2 | semmle.label | s2 | | test.c:98:40:98:41 | s2 | semmle.label | s2 | | test.c:99:3:99:4 | s3 | semmle.label | s3 | | test.c:100:10:100:11 | s3 | semmle.label | s3 | subpaths #select -| test.c:6:19:6:20 | & ... | test.c:6:19:6:20 | & ... | test.c:6:19:6:20 | & ... | Cast from float to int results in an incompatible pointer base type. | -| test.c:11:10:11:11 | & ... | test.c:11:10:11:11 | & ... | test.c:11:10:11:11 | & ... | Cast from short[2] to int results in an incompatible pointer base type. | -| test.c:13:17:13:19 | & ... | test.c:13:17:13:19 | & ... | test.c:13:17:13:19 | & ... | Cast from short[2] to short[4] results in an incompatible pointer base type. | -| test.c:19:18:19:20 | & ... | test.c:19:18:19:20 | & ... | test.c:19:18:19:20 | & ... | Cast from char to signed char results in an incompatible pointer base type. | -| test.c:30:19:30:21 | & ... | test.c:30:19:30:21 | & ... | test.c:30:19:30:21 | & ... | Cast from int to unsigned int results in an incompatible pointer base type. | +| test.c:6:19:6:20 | & ... | test.c:6:12:6:20 | & ... | test.c:6:12:6:20 | & ... | Cast from float to int results in an incompatible pointer base type. | +| test.c:11:10:11:11 | & ... | test.c:11:3:11:11 | & ... | test.c:11:3:11:11 | & ... | Cast from short[2] to int results in an incompatible pointer base type. | +| test.c:13:17:13:19 | & ... | test.c:13:3:13:19 | & ... | test.c:13:3:13:19 | & ... | Cast from short[2] to short[4] results in an incompatible pointer base type. | +| test.c:19:18:19:20 | & ... | test.c:19:3:19:20 | & ... | test.c:19:3:19:20 | & ... | Cast from char to signed char results in an incompatible pointer base type. | +| test.c:30:19:30:21 | & ... | test.c:30:3:30:21 | & ... | test.c:30:3:30:21 | & ... | Cast from int to unsigned int results in an incompatible pointer base type. | | test.c:47:8:47:9 | s2 | test.c:47:8:47:9 | s2 | test.c:47:8:47:9 | s2 | Cast from (unnamed class/struct/union) to (unnamed class/struct/union) results in an incompatible pointer base type. | | test.c:49:8:49:9 | s3 | test.c:49:8:49:9 | s3 | test.c:49:8:49:9 | s3 | Cast from S1 to (unnamed class/struct/union) results in an incompatible pointer base type. | | test.c:50:8:50:9 | s1 | test.c:50:8:50:9 | s1 | test.c:50:8:50:9 | s1 | Cast from (unnamed class/struct/union) to S1 results in an incompatible pointer base type. | -| test.c:68:41:68:41 | v | test.c:72:13:72:15 | & ... | test.c:68:41:68:41 | v | Cast from float to int results in an incompatible pointer base type. | +| test.c:68:41:68:41 | v | test.c:72:13:72:15 | & ... | test.c:68:34:68:41 | v | Cast from float to int results in an incompatible pointer base type. | | test.c:99:3:99:4 | s3 | test.c:98:40:98:41 | s2 | test.c:99:3:99:4 | s3 | Cast from S2 to S3 results in an incompatible pointer base type. | diff --git a/change_notes/2026-09-20-update-exp39-c-to-use-new-dataflow.md b/change_notes/2026-09-20-update-exp39-c-to-use-new-dataflow.md new file mode 100644 index 0000000000..381d9d3161 --- /dev/null +++ b/change_notes/2026-09-20-update-exp39-c-to-use-new-dataflow.md @@ -0,0 +1,3 @@ + - `EXP39-C` - `DoNotAccessVariableViaPointerOfIncompatibleType.ql` + - Updated the underlying dataflow library to use the new dataflow from the deprecated old data flow. This may cause behavioral changes in some analyses, usually with improved results and performance. + - Some refactoring required to accommodate functional changes in how dataflow nodes attach to the AST. No functional changes to the analysis from this are expected. \ No newline at end of file