Merge pull request #12690 from michaelnebel/csharp/checkedlocalflow

C#: Dataflow via checked and unchecked expressions.
This commit is contained in:
Michael Nebel
2023-03-31 10:12:01 +02:00
committed by GitHub
4 changed files with 137 additions and 0 deletions

View File

@@ -239,6 +239,14 @@ module LocalFlow {
scope = e2 and
isSuccessor = true
or
e1 = e2.(CheckedExpr).getExpr() and
scope = e2 and
isSuccessor = true
or
e1 = e2.(UncheckedExpr).getExpr() and
scope = e2 and
isSuccessor = true
or
exists(WithExpr we |
scope = we and
isSuccessor = true

View File

@@ -0,0 +1,38 @@
public class Operators
{
static void Sink(object o) { }
static T Source<T>(object source) => throw null;
public class C
{
public static C operator +(C x, C y) => x;
public static C operator checked -(C x, C y) => y;
public static C operator -(C x, C y) => x;
}
public void M1()
{
var x = Source<C>(1);
var y = Source<C>(2);
var z = x + y;
Sink(z); // $ hasValueFlow=1
}
public void M2()
{
var x = Source<C>(3);
var y = Source<C>(4);
var z = unchecked(x - y);
Sink(z); // $ hasValueFlow=3
}
public void M3()
{
var x = Source<C>(5);
var y = Source<C>(6);
var z = checked(x - y);
Sink(z); // $ hasValueFlow=6
}
}

View File

@@ -0,0 +1,80 @@
failures
edges
| Operator.cs:9:38:9:38 | x : C | Operator.cs:9:49:9:49 | access to parameter x : C |
| Operator.cs:9:38:9:38 | x : C | Operator.cs:9:49:9:49 | access to parameter x : C |
| Operator.cs:11:51:11:51 | y : C | Operator.cs:11:57:11:57 | access to parameter y : C |
| Operator.cs:11:51:11:51 | y : C | Operator.cs:11:57:11:57 | access to parameter y : C |
| Operator.cs:12:38:12:38 | x : C | Operator.cs:12:49:12:49 | access to parameter x : C |
| Operator.cs:12:38:12:38 | x : C | Operator.cs:12:49:12:49 | access to parameter x : C |
| Operator.cs:17:17:17:28 | call to method Source<C> : C | Operator.cs:19:17:19:17 | access to local variable x : C |
| Operator.cs:17:17:17:28 | call to method Source<C> : C | Operator.cs:19:17:19:17 | access to local variable x : C |
| Operator.cs:19:17:19:17 | access to local variable x : C | Operator.cs:9:38:9:38 | x : C |
| Operator.cs:19:17:19:17 | access to local variable x : C | Operator.cs:9:38:9:38 | x : C |
| Operator.cs:19:17:19:17 | access to local variable x : C | Operator.cs:19:17:19:21 | call to operator + : C |
| Operator.cs:19:17:19:17 | access to local variable x : C | Operator.cs:19:17:19:21 | call to operator + : C |
| Operator.cs:19:17:19:21 | call to operator + : C | Operator.cs:20:14:20:14 | access to local variable z |
| Operator.cs:19:17:19:21 | call to operator + : C | Operator.cs:20:14:20:14 | access to local variable z |
| Operator.cs:25:17:25:28 | call to method Source<C> : C | Operator.cs:27:27:27:27 | access to local variable x : C |
| Operator.cs:25:17:25:28 | call to method Source<C> : C | Operator.cs:27:27:27:27 | access to local variable x : C |
| Operator.cs:27:27:27:27 | access to local variable x : C | Operator.cs:12:38:12:38 | x : C |
| Operator.cs:27:27:27:27 | access to local variable x : C | Operator.cs:12:38:12:38 | x : C |
| Operator.cs:27:27:27:27 | access to local variable x : C | Operator.cs:27:27:27:31 | call to operator - : C |
| Operator.cs:27:27:27:27 | access to local variable x : C | Operator.cs:27:27:27:31 | call to operator - : C |
| Operator.cs:27:27:27:31 | call to operator - : C | Operator.cs:28:14:28:14 | access to local variable z |
| Operator.cs:27:27:27:31 | call to operator - : C | Operator.cs:28:14:28:14 | access to local variable z |
| Operator.cs:34:17:34:28 | call to method Source<C> : C | Operator.cs:35:29:35:29 | access to local variable y : C |
| Operator.cs:34:17:34:28 | call to method Source<C> : C | Operator.cs:35:29:35:29 | access to local variable y : C |
| Operator.cs:35:25:35:29 | call to operator checked - : C | Operator.cs:36:14:36:14 | access to local variable z |
| Operator.cs:35:25:35:29 | call to operator checked - : C | Operator.cs:36:14:36:14 | access to local variable z |
| Operator.cs:35:29:35:29 | access to local variable y : C | Operator.cs:11:51:11:51 | y : C |
| Operator.cs:35:29:35:29 | access to local variable y : C | Operator.cs:11:51:11:51 | y : C |
| Operator.cs:35:29:35:29 | access to local variable y : C | Operator.cs:35:25:35:29 | call to operator checked - : C |
| Operator.cs:35:29:35:29 | access to local variable y : C | Operator.cs:35:25:35:29 | call to operator checked - : C |
nodes
| Operator.cs:9:38:9:38 | x : C | semmle.label | x : C |
| Operator.cs:9:38:9:38 | x : C | semmle.label | x : C |
| Operator.cs:9:49:9:49 | access to parameter x : C | semmle.label | access to parameter x : C |
| Operator.cs:9:49:9:49 | access to parameter x : C | semmle.label | access to parameter x : C |
| Operator.cs:11:51:11:51 | y : C | semmle.label | y : C |
| Operator.cs:11:51:11:51 | y : C | semmle.label | y : C |
| Operator.cs:11:57:11:57 | access to parameter y : C | semmle.label | access to parameter y : C |
| Operator.cs:11:57:11:57 | access to parameter y : C | semmle.label | access to parameter y : C |
| Operator.cs:12:38:12:38 | x : C | semmle.label | x : C |
| Operator.cs:12:38:12:38 | x : C | semmle.label | x : C |
| Operator.cs:12:49:12:49 | access to parameter x : C | semmle.label | access to parameter x : C |
| Operator.cs:12:49:12:49 | access to parameter x : C | semmle.label | access to parameter x : C |
| Operator.cs:17:17:17:28 | call to method Source<C> : C | semmle.label | call to method Source<C> : C |
| Operator.cs:17:17:17:28 | call to method Source<C> : C | semmle.label | call to method Source<C> : C |
| Operator.cs:19:17:19:17 | access to local variable x : C | semmle.label | access to local variable x : C |
| Operator.cs:19:17:19:17 | access to local variable x : C | semmle.label | access to local variable x : C |
| Operator.cs:19:17:19:21 | call to operator + : C | semmle.label | call to operator + : C |
| Operator.cs:19:17:19:21 | call to operator + : C | semmle.label | call to operator + : C |
| Operator.cs:20:14:20:14 | access to local variable z | semmle.label | access to local variable z |
| Operator.cs:20:14:20:14 | access to local variable z | semmle.label | access to local variable z |
| Operator.cs:25:17:25:28 | call to method Source<C> : C | semmle.label | call to method Source<C> : C |
| Operator.cs:25:17:25:28 | call to method Source<C> : C | semmle.label | call to method Source<C> : C |
| Operator.cs:27:27:27:27 | access to local variable x : C | semmle.label | access to local variable x : C |
| Operator.cs:27:27:27:27 | access to local variable x : C | semmle.label | access to local variable x : C |
| Operator.cs:27:27:27:31 | call to operator - : C | semmle.label | call to operator - : C |
| Operator.cs:27:27:27:31 | call to operator - : C | semmle.label | call to operator - : C |
| Operator.cs:28:14:28:14 | access to local variable z | semmle.label | access to local variable z |
| Operator.cs:28:14:28:14 | access to local variable z | semmle.label | access to local variable z |
| Operator.cs:34:17:34:28 | call to method Source<C> : C | semmle.label | call to method Source<C> : C |
| Operator.cs:34:17:34:28 | call to method Source<C> : C | semmle.label | call to method Source<C> : C |
| Operator.cs:35:25:35:29 | call to operator checked - : C | semmle.label | call to operator checked - : C |
| Operator.cs:35:25:35:29 | call to operator checked - : C | semmle.label | call to operator checked - : C |
| Operator.cs:35:29:35:29 | access to local variable y : C | semmle.label | access to local variable y : C |
| Operator.cs:35:29:35:29 | access to local variable y : C | semmle.label | access to local variable y : C |
| Operator.cs:36:14:36:14 | access to local variable z | semmle.label | access to local variable z |
| Operator.cs:36:14:36:14 | access to local variable z | semmle.label | access to local variable z |
subpaths
| Operator.cs:19:17:19:17 | access to local variable x : C | Operator.cs:9:38:9:38 | x : C | Operator.cs:9:49:9:49 | access to parameter x : C | Operator.cs:19:17:19:21 | call to operator + : C |
| Operator.cs:19:17:19:17 | access to local variable x : C | Operator.cs:9:38:9:38 | x : C | Operator.cs:9:49:9:49 | access to parameter x : C | Operator.cs:19:17:19:21 | call to operator + : C |
| Operator.cs:27:27:27:27 | access to local variable x : C | Operator.cs:12:38:12:38 | x : C | Operator.cs:12:49:12:49 | access to parameter x : C | Operator.cs:27:27:27:31 | call to operator - : C |
| Operator.cs:27:27:27:27 | access to local variable x : C | Operator.cs:12:38:12:38 | x : C | Operator.cs:12:49:12:49 | access to parameter x : C | Operator.cs:27:27:27:31 | call to operator - : C |
| Operator.cs:35:29:35:29 | access to local variable y : C | Operator.cs:11:51:11:51 | y : C | Operator.cs:11:57:11:57 | access to parameter y : C | Operator.cs:35:25:35:29 | call to operator checked - : C |
| Operator.cs:35:29:35:29 | access to local variable y : C | Operator.cs:11:51:11:51 | y : C | Operator.cs:11:57:11:57 | access to parameter y : C | Operator.cs:35:25:35:29 | call to operator checked - : C |
#select
| Operator.cs:20:14:20:14 | access to local variable z | Operator.cs:17:17:17:28 | call to method Source<C> : C | Operator.cs:20:14:20:14 | access to local variable z | $@ | Operator.cs:17:17:17:28 | call to method Source<C> : C | call to method Source<C> : C |
| Operator.cs:28:14:28:14 | access to local variable z | Operator.cs:25:17:25:28 | call to method Source<C> : C | Operator.cs:28:14:28:14 | access to local variable z | $@ | Operator.cs:25:17:25:28 | call to method Source<C> : C | call to method Source<C> : C |
| Operator.cs:36:14:36:14 | access to local variable z | Operator.cs:34:17:34:28 | call to method Source<C> : C | Operator.cs:36:14:36:14 | access to local variable z | $@ | Operator.cs:34:17:34:28 | call to method Source<C> : C | call to method Source<C> : C |

View File

@@ -0,0 +1,11 @@
/**
* @kind path-problem
*/
import csharp
import DataFlow::PathGraph
import TestUtilities.InlineFlowTest
from DataFlow::PathNode source, DataFlow::PathNode sink, DefaultValueFlowConf conf
where conf.hasFlowPath(source, sink)
select sink, source, sink, "$@", source, source.toString()