|
18 | 18 |
|
19 | 19 | import cpp |
20 | 20 | import semmle.code.cpp.ir.dataflow.DataFlow |
21 | | -import DataFlow::PathGraph |
| 21 | +import CastToPointerArithFlow::PathGraph |
22 | 22 |
|
23 | 23 | Type getFullyConvertedType(DataFlow::Node node) { |
24 | 24 | result = node.asExpr().getFullyConverted().getUnspecifiedType() |
25 | 25 | } |
26 | 26 |
|
27 | | -class CastToPointerArithFlow extends DataFlow::Configuration { |
28 | | - CastToPointerArithFlow() { this = "CastToPointerArithFlow" } |
| 27 | +module CastToPointerArithFlowConfig implements DataFlow::StateConfigSig { |
| 28 | + class FlowState = Type; |
29 | 29 |
|
30 | | - override predicate isSource(DataFlow::Node node, DataFlow::FlowState state) { |
| 30 | + predicate isSource(DataFlow::Node node, FlowState state) { |
31 | 31 | not node.asExpr() instanceof Conversion and |
32 | 32 | exists(Type baseType1, Type baseType2 | |
33 | 33 | hasBaseType(node.asExpr(), baseType1) and |
34 | 34 | hasBaseType(node.asExpr().getConversion*(), baseType2) and |
35 | 35 | introducesNewField(baseType1, baseType2) |
36 | 36 | ) and |
37 | | - getFullyConvertedType(node).getName() = state |
| 37 | + getFullyConvertedType(node) = state |
38 | 38 | } |
39 | 39 |
|
40 | | - override predicate isSink(DataFlow::Node node, DataFlow::FlowState state) { |
| 40 | + predicate isSink(DataFlow::Node node, FlowState state) { |
41 | 41 | ( |
42 | 42 | exists(PointerAddExpr pae | pae.getAnOperand() = node.asExpr()) or |
43 | 43 | exists(ArrayExpr ae | ae.getArrayBase() = node.asExpr()) |
44 | 44 | ) and |
45 | | - getFullyConvertedType(node).getName() = state |
| 45 | + getFullyConvertedType(node) = state |
| 46 | + } |
| 47 | + |
| 48 | + predicate isBarrier(DataFlow::Node node, FlowState state) { none() } |
| 49 | + |
| 50 | + predicate isAdditionalFlowStep( |
| 51 | + DataFlow::Node node1, FlowState state1, DataFlow::Node node2, FlowState state2 |
| 52 | + ) { |
| 53 | + none() |
46 | 54 | } |
47 | 55 | } |
48 | 56 |
|
@@ -72,15 +80,9 @@ predicate introducesNewField(Class derived, Class base) { |
72 | 80 | ) |
73 | 81 | } |
74 | 82 |
|
75 | | -pragma[nomagic] |
76 | | -predicate hasFullyConvertedType(DataFlow::PathNode node, Type t) { |
77 | | - getFullyConvertedType(node.getNode()) = t |
78 | | -} |
| 83 | +module CastToPointerArithFlow = DataFlow::MakeWithState<CastToPointerArithFlowConfig>; |
79 | 84 |
|
80 | | -from DataFlow::PathNode source, DataFlow::PathNode sink, CastToPointerArithFlow cfg, Type t |
81 | | -where |
82 | | - cfg.hasFlowPath(pragma[only_bind_into](source), pragma[only_bind_into](sink)) and |
83 | | - hasFullyConvertedType(source, t) and |
84 | | - hasFullyConvertedType(sink, t) |
| 85 | +from CastToPointerArithFlow::PathNode source, CastToPointerArithFlow::PathNode sink |
| 86 | +where CastToPointerArithFlow::hasFlowPath(source, sink) |
85 | 87 | select sink, source, sink, "This pointer arithmetic may be done with the wrong type because of $@.", |
86 | 88 | source, "this cast" |
0 commit comments