C#: Add test that demonstrates issue with guards logic for foreach statements

This commit is contained in:
Tom Hvitved
2020-08-28 15:13:18 +02:00
parent 67278d9c93
commit ddb33c914b
5 changed files with 64 additions and 41 deletions

View File

@@ -18,7 +18,7 @@ abstractValue
| 0 | Collections.cs:78:36:78:36 | 0 |
| 0 | Collections.cs:80:35:80:35 | 0 |
| 0 | Collections.cs:81:36:81:36 | 0 |
| 0 | Collections.cs:87:17:87:31 | 0 |
| 0 | Collections.cs:87:17:87:32 | 0 |
| 0 | Guards.cs:12:24:12:24 | 0 |
| 0 | Guards.cs:78:26:78:26 | 0 |
| 0 | Guards.cs:80:25:80:25 | 0 |
@@ -59,8 +59,8 @@ abstractValue
| 1 | Guards.cs:331:17:331:19 | access to constant B |
| 1 | Guards.cs:334:13:334:15 | access to constant B |
| 1 | Guards.cs:335:18:335:18 | 1 |
| 3 | Collections.cs:55:13:55:41 | 3 |
| 3 | Collections.cs:63:17:63:45 | 3 |
| 3 | Collections.cs:55:13:55:42 | 3 |
| 3 | Collections.cs:63:17:63:46 | 3 |
| 10 | Guards.cs:84:25:84:26 | 10 |
| 10 | Guards.cs:86:26:86:27 | 10 |
| empty | Collections.cs:54:13:54:16 | access to parameter args |
@@ -69,22 +69,22 @@ abstractValue
| empty | Collections.cs:58:9:58:13 | ... = ... |
| empty | Collections.cs:58:13:58:13 | access to local variable x |
| empty | Collections.cs:65:13:65:13 | access to local variable x |
| empty | Collections.cs:87:17:87:31 | array creation of type String[] |
| empty | Collections.cs:87:30:87:31 | { ..., ... } |
| empty | Collections.cs:88:22:88:23 | { ..., ... } |
| empty | Collections.cs:87:17:87:32 | array creation of type String[] |
| empty | Collections.cs:87:30:87:32 | { ..., ... } |
| empty | Collections.cs:88:22:88:24 | { ..., ... } |
| false | Guards.cs:178:16:178:20 | false |
| false | Guards.cs:181:53:181:57 | false |
| false | Guards.cs:217:18:217:22 | false |
| false | Guards.cs:228:18:228:22 | false |
| false | Guards.cs:295:18:295:22 | false |
| false | Guards.cs:305:18:305:22 | false |
| non-empty | Collections.cs:55:9:55:41 | ... = ... |
| non-empty | Collections.cs:55:13:55:41 | array creation of type String[] |
| non-empty | Collections.cs:55:25:55:41 | { ..., ... } |
| non-empty | Collections.cs:55:9:55:42 | ... = ... |
| non-empty | Collections.cs:55:13:55:42 | array creation of type String[] |
| non-empty | Collections.cs:55:26:55:42 | { ..., ... } |
| non-empty | Collections.cs:56:9:56:13 | ... = ... |
| non-empty | Collections.cs:56:13:56:13 | access to local variable x |
| non-empty | Collections.cs:63:17:63:45 | array creation of type String[] |
| non-empty | Collections.cs:63:29:63:45 | { ..., ... } |
| non-empty | Collections.cs:63:17:63:46 | array creation of type String[] |
| non-empty | Collections.cs:63:30:63:46 | { ..., ... } |
| non-empty | Collections.cs:68:13:68:13 | access to local variable x |
| non-empty | Collections.cs:89:9:89:32 | ... = ... |
| non-empty | Collections.cs:89:13:89:32 | array creation of type String[] |
@@ -155,11 +155,11 @@ abstractValue
| non-null | Collections.cs:54:13:54:16 | access to parameter args |
| non-null | Collections.cs:54:13:54:26 | call to method ToArray |
| non-null | Collections.cs:55:9:55:9 | access to local variable x |
| non-null | Collections.cs:55:9:55:41 | ... = ... |
| non-null | Collections.cs:55:13:55:41 | array creation of type String[] |
| non-null | Collections.cs:55:27:55:29 | "a" |
| non-null | Collections.cs:55:32:55:34 | "b" |
| non-null | Collections.cs:55:37:55:39 | "c" |
| non-null | Collections.cs:55:9:55:42 | ... = ... |
| non-null | Collections.cs:55:13:55:42 | array creation of type String[] |
| non-null | Collections.cs:55:28:55:30 | "a" |
| non-null | Collections.cs:55:33:55:35 | "b" |
| non-null | Collections.cs:55:38:55:40 | "c" |
| non-null | Collections.cs:56:9:56:9 | access to local variable x |
| non-null | Collections.cs:56:9:56:13 | ... = ... |
| non-null | Collections.cs:56:13:56:13 | access to local variable x |
@@ -169,11 +169,11 @@ abstractValue
| non-null | Collections.cs:58:9:58:9 | access to local variable x |
| non-null | Collections.cs:58:9:58:13 | ... = ... |
| non-null | Collections.cs:58:13:58:13 | access to local variable x |
| non-null | Collections.cs:63:17:63:45 | array creation of type String[] |
| non-null | Collections.cs:63:17:63:54 | call to method ToList |
| non-null | Collections.cs:63:31:63:33 | "a" |
| non-null | Collections.cs:63:36:63:38 | "b" |
| non-null | Collections.cs:63:41:63:43 | "c" |
| non-null | Collections.cs:63:17:63:46 | array creation of type String[] |
| non-null | Collections.cs:63:17:63:55 | call to method ToList |
| non-null | Collections.cs:63:32:63:34 | "a" |
| non-null | Collections.cs:63:37:63:39 | "b" |
| non-null | Collections.cs:63:42:63:44 | "c" |
| non-null | Collections.cs:64:9:64:9 | access to local variable x |
| non-null | Collections.cs:65:13:65:13 | access to local variable x |
| non-null | Collections.cs:67:13:67:13 | access to local variable x |
@@ -214,14 +214,20 @@ abstractValue
| non-null | Collections.cs:82:24:82:30 | access to local function IsEmpty |
| non-null | Collections.cs:82:24:82:30 | delegate creation of type Func<String,Boolean> |
| non-null | Collections.cs:82:24:82:30 | this access |
| non-null | Collections.cs:87:17:87:31 | array creation of type String[] |
| non-null | Collections.cs:88:22:88:23 | array creation of type String[] |
| non-null | Collections.cs:87:17:87:32 | array creation of type String[] |
| non-null | Collections.cs:88:22:88:24 | array creation of type String[] |
| non-null | Collections.cs:89:9:89:9 | access to local variable x |
| non-null | Collections.cs:89:9:89:32 | ... = ... |
| non-null | Collections.cs:89:13:89:32 | array creation of type String[] |
| non-null | Collections.cs:89:28:89:30 | "a" |
| non-null | Collections.cs:90:22:90:28 | array creation of type String[] |
| non-null | Collections.cs:90:24:90:26 | "a" |
| non-null | Collections.cs:95:29:95:32 | access to parameter args |
| non-null | Collections.cs:96:13:96:19 | access to type Console |
| non-null | Collections.cs:96:31:96:34 | access to parameter args |
| non-null | Collections.cs:101:29:101:32 | access to parameter args |
| non-null | Collections.cs:103:9:103:15 | access to type Console |
| non-null | Collections.cs:103:27:103:30 | access to parameter args |
| non-null | Guards.cs:12:13:12:13 | access to parameter s |
| non-null | Guards.cs:14:13:14:19 | access to type Console |
| non-null | Guards.cs:14:31:14:31 | access to parameter s |

View File

@@ -52,7 +52,7 @@ public class Collections
var x = args.ToArray();
args.Clear();
x = args.ToArray();
x = new string[]{ "a", "b", "c" };
x = new string[] { "a", "b", "c" };
x = x;
x = new string[0];
x = x;
@@ -60,7 +60,7 @@ public class Collections
void M6()
{
var x = new string[]{ "a", "b", "c" }.ToList();
var x = new string[] { "a", "b", "c" }.ToList();
x.Clear();
if (x.Count == 0)
{
@@ -84,10 +84,23 @@ public class Collections
void M8()
{
var x = new string[] {};
string[] y = {};
var x = new string[] { };
string[] y = { };
x = new string[] { "a" };
string[] z = { "a" };
}
void M9(string[] args)
{
foreach (var arg in args)
Console.WriteLine(args); // guarded by `args` being non-empty
}
void M10(string[] args)
{
foreach (var arg in args)
;
Console.WriteLine(args); // INCORRECT: guarded by `args` being empty
}
}

View File

@@ -37,6 +37,8 @@
| Collections.cs:67:13:67:13 | access to local variable x | Collections.cs:65:13:65:13 | access to local variable x | Collections.cs:65:13:65:13 | access to local variable x | empty |
| Collections.cs:67:13:67:13 | access to local variable x | Collections.cs:65:13:65:24 | ... == ... | Collections.cs:65:13:65:13 | access to local variable x | true |
| Collections.cs:68:13:68:13 | access to local variable x | Collections.cs:65:13:65:24 | ... == ... | Collections.cs:65:13:65:13 | access to local variable x | true |
| Collections.cs:96:31:96:34 | access to parameter args | Collections.cs:95:29:95:32 | access to parameter args | Collections.cs:95:29:95:32 | access to parameter args | non-empty |
| Collections.cs:103:27:103:30 | access to parameter args | Collections.cs:101:29:101:32 | access to parameter args | Collections.cs:101:29:101:32 | access to parameter args | empty |
| Guards.cs:12:13:12:13 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | non-null |
| Guards.cs:12:13:12:13 | access to parameter s | Guards.cs:10:16:10:24 | ... == ... | Guards.cs:10:16:10:16 | access to parameter s | false |
| Guards.cs:14:31:14:31 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | non-null |

View File

@@ -37,6 +37,8 @@
| Collections.cs:67:13:67:13 | access to local variable x | Collections.cs:65:13:65:13 | access to local variable x | Collections.cs:65:13:65:13 | access to local variable x | empty |
| Collections.cs:67:13:67:13 | access to local variable x | Collections.cs:65:13:65:24 | ... == ... | Collections.cs:65:13:65:13 | access to local variable x | true |
| Collections.cs:68:13:68:13 | access to local variable x | Collections.cs:65:13:65:24 | ... == ... | Collections.cs:65:13:65:13 | access to local variable x | true |
| Collections.cs:96:31:96:34 | access to parameter args | Collections.cs:95:29:95:32 | access to parameter args | Collections.cs:95:29:95:32 | access to parameter args | non-empty |
| Collections.cs:103:27:103:30 | access to parameter args | Collections.cs:101:29:101:32 | access to parameter args | Collections.cs:101:29:101:32 | access to parameter args | empty |
| Guards.cs:12:13:12:13 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | non-null |
| Guards.cs:12:13:12:13 | access to parameter s | Guards.cs:10:16:10:24 | ... == ... | Guards.cs:10:16:10:16 | access to parameter s | false |
| Guards.cs:14:31:14:31 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | Guards.cs:10:16:10:16 | access to parameter s | non-null |

View File

@@ -180,26 +180,26 @@
| Collections.cs:45:17:45:26 | call to method Any | true | Collections.cs:45:17:45:20 | access to parameter args | non-empty |
| Collections.cs:50:13:50:27 | ... == ... | false | Collections.cs:50:13:50:16 | access to parameter args | non-empty |
| Collections.cs:50:13:50:27 | ... == ... | true | Collections.cs:50:13:50:16 | access to parameter args | empty |
| Collections.cs:56:13:56:13 | access to local variable x | empty | Collections.cs:55:13:55:41 | array creation of type String[] | empty |
| Collections.cs:56:13:56:13 | access to local variable x | non-empty | Collections.cs:55:13:55:41 | array creation of type String[] | non-empty |
| Collections.cs:56:13:56:13 | access to local variable x | non-null | Collections.cs:55:13:55:41 | array creation of type String[] | non-null |
| Collections.cs:56:13:56:13 | access to local variable x | null | Collections.cs:55:13:55:41 | array creation of type String[] | null |
| Collections.cs:56:13:56:13 | access to local variable x | empty | Collections.cs:55:13:55:42 | array creation of type String[] | empty |
| Collections.cs:56:13:56:13 | access to local variable x | non-empty | Collections.cs:55:13:55:42 | array creation of type String[] | non-empty |
| Collections.cs:56:13:56:13 | access to local variable x | non-null | Collections.cs:55:13:55:42 | array creation of type String[] | non-null |
| Collections.cs:56:13:56:13 | access to local variable x | null | Collections.cs:55:13:55:42 | array creation of type String[] | null |
| Collections.cs:58:13:58:13 | access to local variable x | empty | Collections.cs:57:13:57:25 | array creation of type String[] | empty |
| Collections.cs:58:13:58:13 | access to local variable x | non-empty | Collections.cs:57:13:57:25 | array creation of type String[] | non-empty |
| Collections.cs:58:13:58:13 | access to local variable x | non-null | Collections.cs:57:13:57:25 | array creation of type String[] | non-null |
| Collections.cs:58:13:58:13 | access to local variable x | null | Collections.cs:57:13:57:25 | array creation of type String[] | null |
| Collections.cs:64:9:64:9 | access to local variable x | empty | Collections.cs:63:17:63:54 | call to method ToList | empty |
| Collections.cs:64:9:64:9 | access to local variable x | non-empty | Collections.cs:63:17:63:54 | call to method ToList | non-empty |
| Collections.cs:64:9:64:9 | access to local variable x | non-null | Collections.cs:63:17:63:54 | call to method ToList | non-null |
| Collections.cs:64:9:64:9 | access to local variable x | null | Collections.cs:63:17:63:54 | call to method ToList | null |
| Collections.cs:65:13:65:13 | access to local variable x | non-null | Collections.cs:63:17:63:54 | call to method ToList | non-null |
| Collections.cs:65:13:65:13 | access to local variable x | null | Collections.cs:63:17:63:54 | call to method ToList | null |
| Collections.cs:64:9:64:9 | access to local variable x | empty | Collections.cs:63:17:63:55 | call to method ToList | empty |
| Collections.cs:64:9:64:9 | access to local variable x | non-empty | Collections.cs:63:17:63:55 | call to method ToList | non-empty |
| Collections.cs:64:9:64:9 | access to local variable x | non-null | Collections.cs:63:17:63:55 | call to method ToList | non-null |
| Collections.cs:64:9:64:9 | access to local variable x | null | Collections.cs:63:17:63:55 | call to method ToList | null |
| Collections.cs:65:13:65:13 | access to local variable x | non-null | Collections.cs:63:17:63:55 | call to method ToList | non-null |
| Collections.cs:65:13:65:13 | access to local variable x | null | Collections.cs:63:17:63:55 | call to method ToList | null |
| Collections.cs:65:13:65:24 | ... == ... | false | Collections.cs:65:13:65:13 | access to local variable x | non-empty |
| Collections.cs:65:13:65:24 | ... == ... | true | Collections.cs:65:13:65:13 | access to local variable x | empty |
| Collections.cs:67:13:67:13 | access to local variable x | non-null | Collections.cs:63:17:63:54 | call to method ToList | non-null |
| Collections.cs:67:13:67:13 | access to local variable x | null | Collections.cs:63:17:63:54 | call to method ToList | null |
| Collections.cs:68:13:68:13 | access to local variable x | non-null | Collections.cs:63:17:63:54 | call to method ToList | non-null |
| Collections.cs:68:13:68:13 | access to local variable x | null | Collections.cs:63:17:63:54 | call to method ToList | null |
| Collections.cs:67:13:67:13 | access to local variable x | non-null | Collections.cs:63:17:63:55 | call to method ToList | non-null |
| Collections.cs:67:13:67:13 | access to local variable x | null | Collections.cs:63:17:63:55 | call to method ToList | null |
| Collections.cs:68:13:68:13 | access to local variable x | non-null | Collections.cs:63:17:63:55 | call to method ToList | non-null |
| Collections.cs:68:13:68:13 | access to local variable x | null | Collections.cs:63:17:63:55 | call to method ToList | null |
| Collections.cs:74:35:74:41 | ... == ... | true | Collections.cs:74:35:74:35 | access to parameter s | non-null |
| Collections.cs:74:35:74:41 | ... == ... | true | Collections.cs:74:40:74:41 | "" | non-null |
| Collections.cs:75:17:75:33 | call to method Any | true | Collections.cs:75:17:75:20 | access to parameter args | non-empty |