File tree Expand file tree Collapse file tree 3 files changed +35
-3
lines changed
lib/semmle/code/cpp/ir/dataflow/internal
test/library-tests/dataflow/dataflow-tests Expand file tree Collapse file tree 3 files changed +35
-3
lines changed Original file line number Diff line number Diff line change @@ -52,12 +52,29 @@ private newtype TIRDataFlowNode =
52
52
TFinalParameterNode ( Parameter p , int indirectionIndex ) {
53
53
exists ( Ssa:: FinalParameterUse use |
54
54
use .getParameter ( ) = p and
55
- use .getIndirectionIndex ( ) = indirectionIndex
55
+ use .getIndirectionIndex ( ) = indirectionIndex and
56
+ parameterIsDefined ( p )
56
57
)
57
58
} or
58
59
TFinalGlobalValue ( Ssa:: GlobalUse globalUse ) or
59
60
TInitialGlobalValue ( Ssa:: GlobalDef globalUse )
60
61
62
+ /**
63
+ * Holds if the value of `*p` (or `**p`, `***p`, etc.) is redefined somewhere in the body
64
+ * of the enclosing function of `p`.
65
+ *
66
+ * Only parameters satisfying this predicate will generate a `FinalParameterNode` transferring
67
+ * flow out of the function.
68
+ */
69
+ private predicate parameterIsDefined ( Parameter p ) {
70
+ exists ( Ssa:: Def def |
71
+ def .getSourceVariable ( ) .getBaseVariable ( ) .( Ssa:: BaseIRVariable ) .getIRVariable ( ) .getAst ( ) = p and
72
+ def .getIndirectionIndex ( ) = 0 and
73
+ def .getIndirection ( ) > 1 and
74
+ not def .getValue ( ) .asInstruction ( ) instanceof InitializeParameterInstruction
75
+ )
76
+ }
77
+
61
78
/**
62
79
* An operand that is defined by a `FieldAddressInstruction`.
63
80
*/
Original file line number Diff line number Diff line change @@ -918,6 +918,8 @@ class Def extends DefOrUse {
918
918
Instruction getAddress ( ) { result = this .getAddressOperand ( ) .getDef ( ) }
919
919
920
920
/**
921
+ * Gets the indirection index of this definition.
922
+ *
921
923
* This predicate ensures that joins go from `defOrUse` to the result
922
924
* instead of the other way around.
923
925
*/
@@ -926,6 +928,19 @@ class Def extends DefOrUse {
926
928
pragma [ only_bind_into ] ( result ) = pragma [ only_bind_out ] ( defOrUse ) .getIndirectionIndex ( )
927
929
}
928
930
931
+ /**
932
+ * Gets the indirection level that this definition is writing to.
933
+ * For instance, `x = y` is a definition of `x` at indirection level 1 and
934
+ * `*x = y` is a definition of `x` at indirection level 2.
935
+ *
936
+ * This predicate ensures that joins go from `defOrUse` to the result
937
+ * instead of the other way around.
938
+ */
939
+ pragma [ inline]
940
+ int getIndirection ( ) {
941
+ pragma [ only_bind_into ] ( result ) = pragma [ only_bind_out ] ( defOrUse ) .getIndirection ( )
942
+ }
943
+
929
944
Node0Impl getValue ( ) { result = defOrUse .getValue ( ) }
930
945
931
946
predicate isCertain ( ) { defOrUse .isCertain ( ) }
Original file line number Diff line number Diff line change @@ -579,13 +579,13 @@ namespace IndirectFlowThroughGlobals {
579
579
}
580
580
}
581
581
582
- void write_to_param (int * x) { // $ ast-def=x ir-def=*x
582
+ void write_to_param (int * x) { // $ ast-def=x
583
583
int s = source ();
584
584
x = &s;
585
585
}
586
586
587
587
void test_write_to_param () {
588
588
int x = 0 ;
589
589
write_to_param (&x);
590
- sink (x); // $ SPURIOUS: ast,ir
590
+ sink (x); // $ SPURIOUS: ast
591
591
}
You can’t perform that action at this time.
0 commit comments