C#: Limit number of non-required CFG splits

This commit is contained in:
Tom Hvitved
2019-02-06 10:01:00 +01:00
parent 7d11eb5758
commit e074daee74
2 changed files with 278 additions and 12 deletions

View File

@@ -13,6 +13,9 @@ private import semmle.code.csharp.controlflow.Guards as Guards
private import ControlFlow
private import SuccessorTypes
/** The maximum number of splits allowed for a given node. */
private int maxSplits() { result = 7 }
cached
private module Cached {
cached
@@ -41,11 +44,13 @@ private module Cached {
TSplitsNil() or
TSplitsCons(SplitInternal head, Splits tail) {
exists(
ControlFlowElement pred, Splits predSplits, ControlFlowElement succ, Completion c, int rnk
|
case2aFromRank(pred, predSplits, succ, tail, c, rnk + 1)
ControlFlowElement pred, Splits predSplits, ControlFlowElement succ, Completion c, int rnk,
int numberOfSplits
|
case2aFromRank(pred, predSplits, succ, tail, c, rnk + 1, numberOfSplits) and
head = case2aSomeAtRank(pred, predSplits, succ, c, rnk)
|
numberOfSplits < maxSplits() or head.getKind().isMandatory()
)
}
@@ -93,6 +98,13 @@ abstract class SplitKind extends TSplitKind {
*/
abstract int getListOrder();
/**
* Holds if a split of this kind is mandatory. That is, a split of this kind must
* be taken into account, regardless of whether we might exceed the maximum number
* of splits (`maxSplits()`).
*/
abstract predicate isMandatory();
/**
* Gets the rank of this split kind among all the split kinds that apply to
* control flow element `cfe`. The rank is based on the order defined by
@@ -264,6 +276,8 @@ module FinallySplitting {
private class FinallySplitKind extends SplitKind, TFinallySplitKind {
override int getListOrder() { result = 0 }
override predicate isMandatory() { any() }
override string toString() { result = "Finally" }
}
@@ -415,6 +429,8 @@ module ExceptionHandlerSplitting {
private class ExceptionHandlerSplitKind extends SplitKind, TExceptionHandlerSplitKind {
override int getListOrder() { result = 1 }
override predicate isMandatory() { any() }
override string toString() { result = "ExceptionHandler" }
}
@@ -711,6 +727,8 @@ module BooleanSplitting {
)
}
override predicate isMandatory() { none() }
override string toString() { result = kind.toString() }
}
@@ -1046,28 +1064,33 @@ private module SuccSplits {
*/
predicate case2aFromRank(
ControlFlowElement pred, Splits predSplits, ControlFlowElement succ, Splits succSplits,
Completion c, int rnk
Completion c, int rnk, int numberOfSplits
) {
case2aux(pred, predSplits, succ, c) and
succSplits = TSplitsNil() and
rnk = max(any(SplitKind sk).getListRank(succ)) + 1
rnk = max(any(SplitKind sk).getListRank(succ)) + 1 and
numberOfSplits = 0
or
case2aFromRank(pred, predSplits, succ, succSplits, c, rnk + 1) and
case2aFromRank(pred, predSplits, succ, succSplits, c, rnk + 1, numberOfSplits) and
case2aNoneAtRank(pred, predSplits, succ, c, rnk)
or
exists(Splits mid, SplitInternal split |
split = case2aCons(pred, predSplits, succ, mid, c, rnk)
exists(Splits mid, SplitInternal split, int numberOfSplitsMid |
split = case2aCons(pred, predSplits, succ, mid, c, rnk, numberOfSplitsMid)
|
succSplits = TSplitsCons(split, mid)
if numberOfSplitsMid < maxSplits() or split.getKind().isMandatory()
then succSplits = TSplitsCons(split, mid) and numberOfSplits = numberOfSplitsMid + 1
else (
succSplits = mid and numberOfSplits = numberOfSplitsMid
)
)
}
pragma[noinline]
private SplitInternal case2aCons(
ControlFlowElement pred, Splits predSplits, ControlFlowElement succ, Splits succSplits,
Completion c, int rnk
Completion c, int rnk, int numberOfSplits
) {
case2aFromRank(pred, predSplits, succ, succSplits, c, rnk + 1) and
case2aFromRank(pred, predSplits, succ, succSplits, c, rnk + 1, numberOfSplits) and
result = case2aSomeAtRank(pred, predSplits, succ, c, rnk)
}
@@ -1101,7 +1124,7 @@ private module SuccSplits {
ControlFlowElement pred, Splits predSplits, ControlFlowElement succ, Splits succSplits,
Completion c
) {
case2aFromRank(pred, predSplits, succ, succSplits, c, 1)
case2aFromRank(pred, predSplits, succ, succSplits, c, 1, _)
or
case2bForall(pred, predSplits, succ, c, TSplitsNil()) and
succSplits = TSplitsNil()

View File

@@ -0,0 +1,243 @@
| SplittingStressTest.cs:4:5:168:5 | {...} | 1 |
| SplittingStressTest.cs:5:9:6:13 | if (...) ... | 1 |
| SplittingStressTest.cs:5:13:5:14 | access to parameter b1 | 1 |
| SplittingStressTest.cs:6:13:6:13 | ; | 1 |
| SplittingStressTest.cs:7:9:8:13 | if (...) ... | 2 |
| SplittingStressTest.cs:7:13:7:14 | access to parameter b2 | 2 |
| SplittingStressTest.cs:8:13:8:13 | ; | 2 |
| SplittingStressTest.cs:9:9:10:13 | if (...) ... | 4 |
| SplittingStressTest.cs:9:13:9:14 | access to parameter b3 | 4 |
| SplittingStressTest.cs:10:13:10:13 | ; | 4 |
| SplittingStressTest.cs:11:9:12:13 | if (...) ... | 8 |
| SplittingStressTest.cs:11:13:11:14 | access to parameter b4 | 8 |
| SplittingStressTest.cs:12:13:12:13 | ; | 8 |
| SplittingStressTest.cs:13:9:14:13 | if (...) ... | 16 |
| SplittingStressTest.cs:13:13:13:14 | access to parameter b5 | 16 |
| SplittingStressTest.cs:14:13:14:13 | ; | 16 |
| SplittingStressTest.cs:15:9:16:13 | if (...) ... | 32 |
| SplittingStressTest.cs:15:13:15:14 | access to parameter b6 | 32 |
| SplittingStressTest.cs:16:13:16:13 | ; | 32 |
| SplittingStressTest.cs:17:9:18:13 | if (...) ... | 64 |
| SplittingStressTest.cs:17:13:17:14 | access to parameter b7 | 64 |
| SplittingStressTest.cs:18:13:18:13 | ; | 64 |
| SplittingStressTest.cs:19:9:20:13 | if (...) ... | 128 |
| SplittingStressTest.cs:19:13:19:14 | access to parameter b8 | 128 |
| SplittingStressTest.cs:20:13:20:13 | ; | 64 |
| SplittingStressTest.cs:21:9:22:13 | if (...) ... | 128 |
| SplittingStressTest.cs:21:13:21:14 | access to parameter b9 | 128 |
| SplittingStressTest.cs:22:13:22:13 | ; | 64 |
| SplittingStressTest.cs:23:9:24:13 | if (...) ... | 128 |
| SplittingStressTest.cs:23:13:23:15 | access to parameter b10 | 128 |
| SplittingStressTest.cs:24:13:24:13 | ; | 64 |
| SplittingStressTest.cs:25:9:26:13 | if (...) ... | 128 |
| SplittingStressTest.cs:25:13:25:15 | access to parameter b11 | 128 |
| SplittingStressTest.cs:26:13:26:13 | ; | 64 |
| SplittingStressTest.cs:27:9:28:13 | if (...) ... | 128 |
| SplittingStressTest.cs:27:13:27:15 | access to parameter b12 | 128 |
| SplittingStressTest.cs:28:13:28:13 | ; | 64 |
| SplittingStressTest.cs:29:9:30:13 | if (...) ... | 128 |
| SplittingStressTest.cs:29:13:29:15 | access to parameter b13 | 128 |
| SplittingStressTest.cs:30:13:30:13 | ; | 64 |
| SplittingStressTest.cs:31:9:32:13 | if (...) ... | 128 |
| SplittingStressTest.cs:31:13:31:15 | access to parameter b14 | 128 |
| SplittingStressTest.cs:32:13:32:13 | ; | 64 |
| SplittingStressTest.cs:33:9:34:13 | if (...) ... | 128 |
| SplittingStressTest.cs:33:13:33:15 | access to parameter b15 | 128 |
| SplittingStressTest.cs:34:13:34:13 | ; | 64 |
| SplittingStressTest.cs:35:9:36:13 | if (...) ... | 128 |
| SplittingStressTest.cs:35:13:35:15 | access to parameter b16 | 128 |
| SplittingStressTest.cs:36:13:36:13 | ; | 64 |
| SplittingStressTest.cs:37:9:38:13 | if (...) ... | 128 |
| SplittingStressTest.cs:37:13:37:15 | access to parameter b17 | 128 |
| SplittingStressTest.cs:38:13:38:13 | ; | 64 |
| SplittingStressTest.cs:39:9:40:13 | if (...) ... | 128 |
| SplittingStressTest.cs:39:13:39:15 | access to parameter b18 | 128 |
| SplittingStressTest.cs:40:13:40:13 | ; | 64 |
| SplittingStressTest.cs:41:9:42:13 | if (...) ... | 128 |
| SplittingStressTest.cs:41:13:41:15 | access to parameter b19 | 128 |
| SplittingStressTest.cs:42:13:42:13 | ; | 64 |
| SplittingStressTest.cs:43:9:44:13 | if (...) ... | 128 |
| SplittingStressTest.cs:43:13:43:15 | access to parameter b20 | 128 |
| SplittingStressTest.cs:44:13:44:13 | ; | 64 |
| SplittingStressTest.cs:45:9:46:13 | if (...) ... | 128 |
| SplittingStressTest.cs:45:13:45:15 | access to parameter b21 | 128 |
| SplittingStressTest.cs:46:13:46:13 | ; | 64 |
| SplittingStressTest.cs:47:9:48:13 | if (...) ... | 128 |
| SplittingStressTest.cs:47:13:47:15 | access to parameter b22 | 128 |
| SplittingStressTest.cs:48:13:48:13 | ; | 64 |
| SplittingStressTest.cs:49:9:50:13 | if (...) ... | 128 |
| SplittingStressTest.cs:49:13:49:15 | access to parameter b23 | 128 |
| SplittingStressTest.cs:50:13:50:13 | ; | 64 |
| SplittingStressTest.cs:51:9:52:13 | if (...) ... | 128 |
| SplittingStressTest.cs:51:13:51:15 | access to parameter b24 | 128 |
| SplittingStressTest.cs:52:13:52:13 | ; | 64 |
| SplittingStressTest.cs:53:9:54:13 | if (...) ... | 128 |
| SplittingStressTest.cs:53:13:53:15 | access to parameter b25 | 128 |
| SplittingStressTest.cs:54:13:54:13 | ; | 64 |
| SplittingStressTest.cs:55:9:56:13 | if (...) ... | 128 |
| SplittingStressTest.cs:55:13:55:15 | access to parameter b26 | 128 |
| SplittingStressTest.cs:56:13:56:13 | ; | 64 |
| SplittingStressTest.cs:57:9:58:13 | if (...) ... | 128 |
| SplittingStressTest.cs:57:13:57:15 | access to parameter b27 | 128 |
| SplittingStressTest.cs:58:13:58:13 | ; | 64 |
| SplittingStressTest.cs:59:9:60:13 | if (...) ... | 128 |
| SplittingStressTest.cs:59:13:59:15 | access to parameter b28 | 128 |
| SplittingStressTest.cs:60:13:60:13 | ; | 64 |
| SplittingStressTest.cs:61:9:62:13 | if (...) ... | 128 |
| SplittingStressTest.cs:61:13:61:15 | access to parameter b29 | 128 |
| SplittingStressTest.cs:62:13:62:13 | ; | 64 |
| SplittingStressTest.cs:63:9:64:13 | if (...) ... | 128 |
| SplittingStressTest.cs:63:13:63:15 | access to parameter b30 | 128 |
| SplittingStressTest.cs:64:13:64:13 | ; | 64 |
| SplittingStressTest.cs:65:9:66:13 | if (...) ... | 128 |
| SplittingStressTest.cs:65:13:65:15 | access to parameter b31 | 128 |
| SplittingStressTest.cs:66:13:66:13 | ; | 64 |
| SplittingStressTest.cs:67:9:68:13 | if (...) ... | 128 |
| SplittingStressTest.cs:67:13:67:15 | access to parameter b32 | 128 |
| SplittingStressTest.cs:68:13:68:13 | ; | 64 |
| SplittingStressTest.cs:69:9:70:13 | if (...) ... | 128 |
| SplittingStressTest.cs:69:13:69:15 | access to parameter b33 | 128 |
| SplittingStressTest.cs:70:13:70:13 | ; | 64 |
| SplittingStressTest.cs:71:9:72:13 | if (...) ... | 128 |
| SplittingStressTest.cs:71:13:71:15 | access to parameter b34 | 128 |
| SplittingStressTest.cs:72:13:72:13 | ; | 64 |
| SplittingStressTest.cs:73:9:74:13 | if (...) ... | 128 |
| SplittingStressTest.cs:73:13:73:15 | access to parameter b35 | 128 |
| SplittingStressTest.cs:74:13:74:13 | ; | 64 |
| SplittingStressTest.cs:75:9:76:13 | if (...) ... | 128 |
| SplittingStressTest.cs:75:13:75:15 | access to parameter b36 | 128 |
| SplittingStressTest.cs:76:13:76:13 | ; | 64 |
| SplittingStressTest.cs:77:9:78:13 | if (...) ... | 128 |
| SplittingStressTest.cs:77:13:77:15 | access to parameter b37 | 128 |
| SplittingStressTest.cs:78:13:78:13 | ; | 64 |
| SplittingStressTest.cs:79:9:80:13 | if (...) ... | 128 |
| SplittingStressTest.cs:79:13:79:15 | access to parameter b38 | 128 |
| SplittingStressTest.cs:80:13:80:13 | ; | 64 |
| SplittingStressTest.cs:81:9:82:13 | if (...) ... | 128 |
| SplittingStressTest.cs:81:13:81:15 | access to parameter b39 | 128 |
| SplittingStressTest.cs:82:13:82:13 | ; | 64 |
| SplittingStressTest.cs:83:9:84:13 | if (...) ... | 128 |
| SplittingStressTest.cs:83:13:83:15 | access to parameter b40 | 128 |
| SplittingStressTest.cs:84:13:84:13 | ; | 64 |
| SplittingStressTest.cs:85:9:85:9 | ; | 128 |
| SplittingStressTest.cs:87:9:88:13 | if (...) ... | 128 |
| SplittingStressTest.cs:87:13:87:14 | access to parameter b1 | 128 |
| SplittingStressTest.cs:88:13:88:13 | ; | 128 |
| SplittingStressTest.cs:89:9:90:13 | if (...) ... | 128 |
| SplittingStressTest.cs:89:13:89:14 | access to parameter b2 | 128 |
| SplittingStressTest.cs:90:13:90:13 | ; | 128 |
| SplittingStressTest.cs:91:9:92:13 | if (...) ... | 128 |
| SplittingStressTest.cs:91:13:91:14 | access to parameter b3 | 128 |
| SplittingStressTest.cs:92:13:92:13 | ; | 128 |
| SplittingStressTest.cs:93:9:94:13 | if (...) ... | 128 |
| SplittingStressTest.cs:93:13:93:14 | access to parameter b4 | 128 |
| SplittingStressTest.cs:94:13:94:13 | ; | 128 |
| SplittingStressTest.cs:95:9:96:13 | if (...) ... | 128 |
| SplittingStressTest.cs:95:13:95:14 | access to parameter b5 | 128 |
| SplittingStressTest.cs:96:13:96:13 | ; | 128 |
| SplittingStressTest.cs:97:9:98:13 | if (...) ... | 128 |
| SplittingStressTest.cs:97:13:97:14 | access to parameter b6 | 128 |
| SplittingStressTest.cs:98:13:98:13 | ; | 128 |
| SplittingStressTest.cs:99:9:100:13 | if (...) ... | 128 |
| SplittingStressTest.cs:99:13:99:14 | access to parameter b7 | 128 |
| SplittingStressTest.cs:100:13:100:13 | ; | 128 |
| SplittingStressTest.cs:101:9:102:13 | if (...) ... | 128 |
| SplittingStressTest.cs:101:13:101:14 | access to parameter b8 | 128 |
| SplittingStressTest.cs:102:13:102:13 | ; | 128 |
| SplittingStressTest.cs:103:9:104:13 | if (...) ... | 128 |
| SplittingStressTest.cs:103:13:103:14 | access to parameter b9 | 128 |
| SplittingStressTest.cs:104:13:104:13 | ; | 128 |
| SplittingStressTest.cs:105:9:106:13 | if (...) ... | 128 |
| SplittingStressTest.cs:105:13:105:15 | access to parameter b10 | 128 |
| SplittingStressTest.cs:106:13:106:13 | ; | 128 |
| SplittingStressTest.cs:107:9:108:13 | if (...) ... | 128 |
| SplittingStressTest.cs:107:13:107:15 | access to parameter b11 | 128 |
| SplittingStressTest.cs:108:13:108:13 | ; | 128 |
| SplittingStressTest.cs:109:9:110:13 | if (...) ... | 128 |
| SplittingStressTest.cs:109:13:109:15 | access to parameter b12 | 128 |
| SplittingStressTest.cs:110:13:110:13 | ; | 128 |
| SplittingStressTest.cs:111:9:112:13 | if (...) ... | 128 |
| SplittingStressTest.cs:111:13:111:15 | access to parameter b13 | 128 |
| SplittingStressTest.cs:112:13:112:13 | ; | 128 |
| SplittingStressTest.cs:113:9:114:13 | if (...) ... | 128 |
| SplittingStressTest.cs:113:13:113:15 | access to parameter b14 | 128 |
| SplittingStressTest.cs:114:13:114:13 | ; | 128 |
| SplittingStressTest.cs:115:9:116:13 | if (...) ... | 128 |
| SplittingStressTest.cs:115:13:115:15 | access to parameter b15 | 128 |
| SplittingStressTest.cs:116:13:116:13 | ; | 128 |
| SplittingStressTest.cs:117:9:118:13 | if (...) ... | 128 |
| SplittingStressTest.cs:117:13:117:15 | access to parameter b16 | 128 |
| SplittingStressTest.cs:118:13:118:13 | ; | 128 |
| SplittingStressTest.cs:119:9:120:13 | if (...) ... | 128 |
| SplittingStressTest.cs:119:13:119:15 | access to parameter b17 | 128 |
| SplittingStressTest.cs:120:13:120:13 | ; | 128 |
| SplittingStressTest.cs:121:9:122:13 | if (...) ... | 128 |
| SplittingStressTest.cs:121:13:121:15 | access to parameter b18 | 128 |
| SplittingStressTest.cs:122:13:122:13 | ; | 128 |
| SplittingStressTest.cs:123:9:124:13 | if (...) ... | 128 |
| SplittingStressTest.cs:123:13:123:15 | access to parameter b19 | 128 |
| SplittingStressTest.cs:124:13:124:13 | ; | 128 |
| SplittingStressTest.cs:125:9:126:13 | if (...) ... | 128 |
| SplittingStressTest.cs:125:13:125:15 | access to parameter b20 | 128 |
| SplittingStressTest.cs:126:13:126:13 | ; | 128 |
| SplittingStressTest.cs:127:9:128:13 | if (...) ... | 128 |
| SplittingStressTest.cs:127:13:127:15 | access to parameter b21 | 128 |
| SplittingStressTest.cs:128:13:128:13 | ; | 128 |
| SplittingStressTest.cs:129:9:130:13 | if (...) ... | 128 |
| SplittingStressTest.cs:129:13:129:15 | access to parameter b22 | 128 |
| SplittingStressTest.cs:130:13:130:13 | ; | 128 |
| SplittingStressTest.cs:131:9:132:13 | if (...) ... | 128 |
| SplittingStressTest.cs:131:13:131:15 | access to parameter b23 | 128 |
| SplittingStressTest.cs:132:13:132:13 | ; | 128 |
| SplittingStressTest.cs:133:9:134:13 | if (...) ... | 128 |
| SplittingStressTest.cs:133:13:133:15 | access to parameter b24 | 128 |
| SplittingStressTest.cs:134:13:134:13 | ; | 128 |
| SplittingStressTest.cs:135:9:136:13 | if (...) ... | 128 |
| SplittingStressTest.cs:135:13:135:15 | access to parameter b25 | 128 |
| SplittingStressTest.cs:136:13:136:13 | ; | 128 |
| SplittingStressTest.cs:137:9:138:13 | if (...) ... | 128 |
| SplittingStressTest.cs:137:13:137:15 | access to parameter b26 | 128 |
| SplittingStressTest.cs:138:13:138:13 | ; | 128 |
| SplittingStressTest.cs:139:9:140:13 | if (...) ... | 128 |
| SplittingStressTest.cs:139:13:139:15 | access to parameter b27 | 128 |
| SplittingStressTest.cs:140:13:140:13 | ; | 128 |
| SplittingStressTest.cs:141:9:142:13 | if (...) ... | 128 |
| SplittingStressTest.cs:141:13:141:15 | access to parameter b28 | 128 |
| SplittingStressTest.cs:142:13:142:13 | ; | 128 |
| SplittingStressTest.cs:143:9:144:13 | if (...) ... | 128 |
| SplittingStressTest.cs:143:13:143:15 | access to parameter b29 | 128 |
| SplittingStressTest.cs:144:13:144:13 | ; | 128 |
| SplittingStressTest.cs:145:9:146:13 | if (...) ... | 128 |
| SplittingStressTest.cs:145:13:145:15 | access to parameter b30 | 128 |
| SplittingStressTest.cs:146:13:146:13 | ; | 128 |
| SplittingStressTest.cs:147:9:148:13 | if (...) ... | 128 |
| SplittingStressTest.cs:147:13:147:15 | access to parameter b31 | 128 |
| SplittingStressTest.cs:148:13:148:13 | ; | 128 |
| SplittingStressTest.cs:149:9:150:13 | if (...) ... | 128 |
| SplittingStressTest.cs:149:13:149:15 | access to parameter b32 | 128 |
| SplittingStressTest.cs:150:13:150:13 | ; | 128 |
| SplittingStressTest.cs:151:9:152:13 | if (...) ... | 128 |
| SplittingStressTest.cs:151:13:151:15 | access to parameter b33 | 128 |
| SplittingStressTest.cs:152:13:152:13 | ; | 128 |
| SplittingStressTest.cs:153:9:154:13 | if (...) ... | 128 |
| SplittingStressTest.cs:153:13:153:15 | access to parameter b34 | 128 |
| SplittingStressTest.cs:154:13:154:13 | ; | 64 |
| SplittingStressTest.cs:155:9:156:13 | if (...) ... | 64 |
| SplittingStressTest.cs:155:13:155:15 | access to parameter b35 | 64 |
| SplittingStressTest.cs:156:13:156:13 | ; | 32 |
| SplittingStressTest.cs:157:9:158:13 | if (...) ... | 32 |
| SplittingStressTest.cs:157:13:157:15 | access to parameter b36 | 32 |
| SplittingStressTest.cs:158:13:158:13 | ; | 16 |
| SplittingStressTest.cs:159:9:160:13 | if (...) ... | 16 |
| SplittingStressTest.cs:159:13:159:15 | access to parameter b37 | 16 |
| SplittingStressTest.cs:160:13:160:13 | ; | 8 |
| SplittingStressTest.cs:161:9:162:13 | if (...) ... | 8 |
| SplittingStressTest.cs:161:13:161:15 | access to parameter b38 | 8 |
| SplittingStressTest.cs:162:13:162:13 | ; | 4 |
| SplittingStressTest.cs:163:9:164:13 | if (...) ... | 4 |
| SplittingStressTest.cs:163:13:163:15 | access to parameter b39 | 4 |
| SplittingStressTest.cs:164:13:164:13 | ; | 2 |
| SplittingStressTest.cs:165:9:166:13 | if (...) ... | 2 |
| SplittingStressTest.cs:165:13:165:15 | access to parameter b40 | 2 |
| SplittingStressTest.cs:166:13:166:13 | ; | 1 |
| SplittingStressTest.cs:167:9:167:9 | ; | 1 |