C#: More tests for nullable flow state.

This commit is contained in:
Calum Grant
2019-11-26 18:09:40 +00:00
committed by Calum Grant
parent 6c9ebaba0b
commit 8db46bc8ec
3 changed files with 164 additions and 66 deletions

View File

@@ -165,3 +165,44 @@ class DisabledNullability
struct MyStruct
{
}
#nullable enable
abstract class TestNullableFlowStates
{
public abstract string? MaybeNull();
public abstract void Check(string? isNull);
public abstract int Count();
void LoopUnrolling()
{
string? x = MaybeNull();
Check(x); // x is maybe null
for (int i = 0; i < 10; ++i)
{
x = "not null any more";
}
Check(x); // x maybe null - loop unrolling not detected
}
void ExceptionFlow()
{
string? y = MaybeNull();
try
{
throw new ArgumentException();
}
finally
{
y = "not null";
}
Check(y); // y not null - finally flow is detected
}
}

View File

@@ -191,6 +191,12 @@ returnTypes
| NullableRefTypes.cs:157:18:157:30 | get_P | MyClass |
| NullableRefTypes.cs:158:13:158:14 | Fn | MyClass |
| NullableRefTypes.cs:165:8:165:15 | MyStruct | Void! |
| NullableRefTypes.cs:171:16:171:37 | TestNullableFlowStates | Void! |
| NullableRefTypes.cs:173:29:173:37 | MaybeNull | string? |
| NullableRefTypes.cs:175:26:175:30 | Check | Void! |
| NullableRefTypes.cs:177:25:177:29 | Count | int! |
| NullableRefTypes.cs:179:10:179:22 | LoopUnrolling | Void! |
| NullableRefTypes.cs:193:10:193:22 | ExceptionFlow | Void! |
methodTypeArguments
| NullableRefTypes.cs:51:12:51:15 | Q | 0 | MyClass! |
| NullableRefTypes.cs:51:12:51:15 | Q | 0 | MyClass? |
@@ -315,62 +321,114 @@ expressionTypes
| NullableRefTypes.cs:160:17:160:21 | MyClass a = ... | MyClass! |
| NullableRefTypes.cs:160:21:160:21 | access to parameter p | MyClass! |
| NullableRefTypes.cs:161:16:161:16 | access to local variable a | MyClass! |
exprMaybeNull
| NullableRefTypes.cs:13:19:13:22 | null |
| NullableRefTypes.cs:17:29:17:32 | null |
| NullableRefTypes.cs:26:50:26:53 | null |
| NullableRefTypes.cs:27:50:27:53 | null |
| NullableRefTypes.cs:30:21:30:24 | null |
| NullableRefTypes.cs:38:22:38:25 | null |
| NullableRefTypes.cs:39:29:39:29 | access to local variable b |
| NullableRefTypes.cs:40:30:40:30 | access to local variable b |
| NullableRefTypes.cs:51:44:51:47 | null |
| NullableRefTypes.cs:73:22:73:25 | null |
| NullableRefTypes.cs:74:19:74:19 | access to local variable x |
| NullableRefTypes.cs:75:11:75:11 | access to local variable x |
| NullableRefTypes.cs:87:9:87:16 | ... = ... |
| NullableRefTypes.cs:87:13:87:16 | null |
| NullableRefTypes.cs:94:17:94:25 | ... ?? ... |
| NullableRefTypes.cs:94:22:94:25 | null |
| NullableRefTypes.cs:95:20:95:20 | access to local variable x |
| NullableRefTypes.cs:96:27:96:27 | access to local variable x |
| NullableRefTypes.cs:104:52:104:52 | access to parameter r |
| NullableRefTypes.cs:105:61:105:61 | access to parameter r |
| NullableRefTypes.cs:108:60:108:60 | access to parameter r |
| NullableRefTypes.cs:110:64:110:67 | null |
exprNotNull
| NullableRefTypes.cs:14:18:14:21 | this access |
| NullableRefTypes.cs:18:31:18:34 | this access |
| NullableRefTypes.cs:19:33:19:36 | this access |
| NullableRefTypes.cs:26:44:26:53 | throw ... |
| NullableRefTypes.cs:27:44:27:53 | throw ... |
| NullableRefTypes.cs:31:20:31:23 | this access |
| NullableRefTypes.cs:37:21:37:33 | object creation of type MyClass |
| NullableRefTypes.cs:74:9:74:20 | call to method GenericFn |
| NullableRefTypes.cs:75:9:75:12 | call to method Q |
| NullableRefTypes.cs:76:16:76:32 | default(...) |
| NullableRefTypes.cs:84:21:84:28 | "source" |
| NullableRefTypes.cs:85:20:85:20 | access to local variable x |
| NullableRefTypes.cs:85:20:85:21 | ...! |
| NullableRefTypes.cs:86:9:86:9 | access to local variable y |
| NullableRefTypes.cs:86:9:86:14 | ... = ... |
| NullableRefTypes.cs:86:13:86:13 | access to local variable x |
| NullableRefTypes.cs:86:13:86:14 | ...! |
| NullableRefTypes.cs:87:9:87:9 | access to local variable x |
| NullableRefTypes.cs:88:9:88:9 | access to local variable y |
| NullableRefTypes.cs:88:9:88:14 | ... = ... |
| NullableRefTypes.cs:88:13:88:13 | access to local variable x |
| NullableRefTypes.cs:88:13:88:14 | ...! |
| NullableRefTypes.cs:93:21:93:28 | "source" |
| NullableRefTypes.cs:94:17:94:17 | access to local variable x |
| NullableRefTypes.cs:96:9:96:15 | access to type Console |
| NullableRefTypes.cs:96:9:96:28 | call to method WriteLine |
| NullableRefTypes.cs:103:52:103:52 | access to parameter r |
| NullableRefTypes.cs:106:60:106:60 | access to parameter r |
| NullableRefTypes.cs:107:59:107:59 | access to parameter r |
| NullableRefTypes.cs:110:58:110:67 | throw ... |
| NullableRefTypes.cs:113:36:113:43 | access to field Property |
| NullableRefTypes.cs:113:36:113:44 | ...! |
| NullableRefTypes.cs:157:18:157:30 | object creation of type MyClass |
| NullableRefTypes.cs:160:21:160:21 | access to parameter p |
| NullableRefTypes.cs:161:16:161:16 | access to local variable a |
| NullableRefTypes.cs:181:17:181:17 | access to local variable x | string! |
| NullableRefTypes.cs:181:17:181:31 | String x = ... | string! |
| NullableRefTypes.cs:181:21:181:31 | call to method MaybeNull | string? |
| NullableRefTypes.cs:181:21:181:31 | this access | TestNullableFlowStates |
| NullableRefTypes.cs:183:9:183:16 | call to method Check | Void! |
| NullableRefTypes.cs:183:9:183:16 | this access | TestNullableFlowStates |
| NullableRefTypes.cs:183:15:183:15 | access to local variable x | string? |
| NullableRefTypes.cs:185:18:185:18 | access to local variable i | int! |
| NullableRefTypes.cs:185:18:185:22 | Int32 i = ... | int! |
| NullableRefTypes.cs:185:22:185:22 | 0 | int! |
| NullableRefTypes.cs:185:25:185:25 | access to local variable i | int! |
| NullableRefTypes.cs:185:25:185:30 | ... < ... | bool! |
| NullableRefTypes.cs:185:29:185:30 | 10 | int! |
| NullableRefTypes.cs:185:33:185:35 | ++... | int! |
| NullableRefTypes.cs:185:35:185:35 | access to local variable i | int! |
| NullableRefTypes.cs:187:13:187:13 | access to local variable x | string? |
| NullableRefTypes.cs:187:13:187:35 | ... = ... | string! |
| NullableRefTypes.cs:187:17:187:35 | "not null any more" | string! |
| NullableRefTypes.cs:190:9:190:16 | call to method Check | Void! |
| NullableRefTypes.cs:190:9:190:16 | this access | TestNullableFlowStates |
| NullableRefTypes.cs:190:15:190:15 | access to local variable x | string? |
| NullableRefTypes.cs:195:17:195:17 | access to local variable y | string! |
| NullableRefTypes.cs:195:17:195:31 | String y = ... | string! |
| NullableRefTypes.cs:195:21:195:31 | call to method MaybeNull | string? |
| NullableRefTypes.cs:195:21:195:31 | this access | TestNullableFlowStates |
| NullableRefTypes.cs:199:19:199:41 | object creation of type ArgumentException | ArgumentException! |
| NullableRefTypes.cs:203:13:203:13 | access to local variable y | string? |
| NullableRefTypes.cs:203:13:203:26 | ... = ... | string! |
| NullableRefTypes.cs:203:17:203:26 | "not null" | string! |
| NullableRefTypes.cs:206:9:206:16 | call to method Check | Void! |
| NullableRefTypes.cs:206:9:206:16 | this access | TestNullableFlowStates |
| NullableRefTypes.cs:206:15:206:15 | access to local variable y | string! |
exprFlowState
| NullableRefTypes.cs:13:19:13:22 | null | Maybe null |
| NullableRefTypes.cs:14:18:14:21 | this access | Not null |
| NullableRefTypes.cs:17:29:17:32 | null | Maybe null |
| NullableRefTypes.cs:18:31:18:34 | this access | Not null |
| NullableRefTypes.cs:19:33:19:36 | this access | Not null |
| NullableRefTypes.cs:26:44:26:53 | throw ... | Not null |
| NullableRefTypes.cs:26:50:26:53 | null | Maybe null |
| NullableRefTypes.cs:27:44:27:53 | throw ... | Not null |
| NullableRefTypes.cs:27:50:27:53 | null | Maybe null |
| NullableRefTypes.cs:30:21:30:24 | null | Maybe null |
| NullableRefTypes.cs:31:20:31:23 | this access | Not null |
| NullableRefTypes.cs:37:21:37:33 | object creation of type MyClass | Not null |
| NullableRefTypes.cs:38:22:38:25 | null | Maybe null |
| NullableRefTypes.cs:39:29:39:29 | access to local variable b | Maybe null |
| NullableRefTypes.cs:40:30:40:30 | access to local variable b | Maybe null |
| NullableRefTypes.cs:51:44:51:47 | null | Maybe null |
| NullableRefTypes.cs:73:22:73:25 | null | Maybe null |
| NullableRefTypes.cs:74:9:74:20 | call to method GenericFn | Not null |
| NullableRefTypes.cs:74:19:74:19 | access to local variable x | Maybe null |
| NullableRefTypes.cs:75:9:75:12 | call to method Q | Not null |
| NullableRefTypes.cs:75:11:75:11 | access to local variable x | Maybe null |
| NullableRefTypes.cs:76:16:76:32 | default(...) | Not null |
| NullableRefTypes.cs:84:21:84:28 | "source" | Not null |
| NullableRefTypes.cs:85:20:85:20 | access to local variable x | Not null |
| NullableRefTypes.cs:85:20:85:21 | ...! | Not null |
| NullableRefTypes.cs:86:9:86:9 | access to local variable y | Not null |
| NullableRefTypes.cs:86:9:86:14 | ... = ... | Not null |
| NullableRefTypes.cs:86:13:86:13 | access to local variable x | Not null |
| NullableRefTypes.cs:86:13:86:14 | ...! | Not null |
| NullableRefTypes.cs:87:9:87:9 | access to local variable x | Not null |
| NullableRefTypes.cs:87:9:87:16 | ... = ... | Maybe null |
| NullableRefTypes.cs:87:13:87:16 | null | Maybe null |
| NullableRefTypes.cs:88:9:88:9 | access to local variable y | Not null |
| NullableRefTypes.cs:88:9:88:14 | ... = ... | Not null |
| NullableRefTypes.cs:88:13:88:13 | access to local variable x | Not null |
| NullableRefTypes.cs:88:13:88:14 | ...! | Not null |
| NullableRefTypes.cs:93:21:93:28 | "source" | Not null |
| NullableRefTypes.cs:94:17:94:17 | access to local variable x | Not null |
| NullableRefTypes.cs:94:17:94:25 | ... ?? ... | Maybe null |
| NullableRefTypes.cs:94:22:94:25 | null | Maybe null |
| NullableRefTypes.cs:95:20:95:20 | access to local variable x | Maybe null |
| NullableRefTypes.cs:96:9:96:15 | access to type Console | Not null |
| NullableRefTypes.cs:96:9:96:28 | call to method WriteLine | Not null |
| NullableRefTypes.cs:96:27:96:27 | access to local variable x | Maybe null |
| NullableRefTypes.cs:103:52:103:52 | access to parameter r | Not null |
| NullableRefTypes.cs:104:52:104:52 | access to parameter r | Maybe null |
| NullableRefTypes.cs:105:61:105:61 | access to parameter r | Maybe null |
| NullableRefTypes.cs:106:60:106:60 | access to parameter r | Not null |
| NullableRefTypes.cs:107:59:107:59 | access to parameter r | Not null |
| NullableRefTypes.cs:108:60:108:60 | access to parameter r | Maybe null |
| NullableRefTypes.cs:110:58:110:67 | throw ... | Not null |
| NullableRefTypes.cs:110:64:110:67 | null | Maybe null |
| NullableRefTypes.cs:113:36:113:43 | access to field Property | Not null |
| NullableRefTypes.cs:113:36:113:44 | ...! | Not null |
| NullableRefTypes.cs:157:18:157:30 | object creation of type MyClass | Not null |
| NullableRefTypes.cs:160:21:160:21 | access to parameter p | Not null |
| NullableRefTypes.cs:161:16:161:16 | access to local variable a | Not null |
| NullableRefTypes.cs:181:21:181:31 | call to method MaybeNull | Maybe null |
| NullableRefTypes.cs:183:9:183:16 | call to method Check | Not null |
| NullableRefTypes.cs:183:15:183:15 | access to local variable x | Maybe null |
| NullableRefTypes.cs:185:22:185:22 | 0 | Not null |
| NullableRefTypes.cs:185:25:185:25 | access to local variable i | Not null |
| NullableRefTypes.cs:185:25:185:30 | ... < ... | Not null |
| NullableRefTypes.cs:185:29:185:30 | 10 | Not null |
| NullableRefTypes.cs:185:33:185:35 | ++... | Not null |
| NullableRefTypes.cs:185:35:185:35 | access to local variable i | Not null |
| NullableRefTypes.cs:187:13:187:13 | access to local variable x | Maybe null |
| NullableRefTypes.cs:187:13:187:35 | ... = ... | Not null |
| NullableRefTypes.cs:187:17:187:35 | "not null any more" | Not null |
| NullableRefTypes.cs:190:9:190:16 | call to method Check | Not null |
| NullableRefTypes.cs:190:15:190:15 | access to local variable x | Maybe null |
| NullableRefTypes.cs:195:21:195:31 | call to method MaybeNull | Maybe null |
| NullableRefTypes.cs:199:19:199:41 | object creation of type ArgumentException | Not null |
| NullableRefTypes.cs:203:13:203:13 | access to local variable y | Maybe null |
| NullableRefTypes.cs:203:13:203:26 | ... = ... | Not null |
| NullableRefTypes.cs:203:17:203:26 | "not null" | Not null |
| NullableRefTypes.cs:206:9:206:16 | call to method Check | Not null |
| NullableRefTypes.cs:206:15:206:15 | access to local variable y | Not null |

View File

@@ -68,12 +68,11 @@ query predicate expressionTypes(Expr expr, string type) {
expr.getFile().getBaseName() = "NullableRefTypes.cs"
}
query predicate exprMaybeNull(Expr expr) {
query predicate exprFlowState(Expr expr, string state) {
expr.getFile().getBaseName() = "NullableRefTypes.cs" and
expr.hasMaybeNullFlowState()
}
query predicate exprNotNull(Expr expr) {
expr.getFile().getBaseName() = "NullableRefTypes.cs" and
expr.hasNotNullFlowState()
(
expr.hasMaybeNullFlowState() and state = "Maybe null"
or
expr.hasNotNullFlowState() and state = "Not null"
)
}