C#静态分析,变量/参数的可能值

C#静态分析,变量/参数的可能值,c#,static-analysis,pex,c#-5.0,roslyn,C#,Static Analysis,Pex,C# 5.0,Roslyn,在与以下每个示例类似的代码中,我希望能够静态分析代码,以确定传递到SpecialFunction()的可能值的列表 我已经可以将C#解析成一个抽象语法树,并且可以处理像A这样的情况,我想我可以跟踪值的初始赋值来猜测情况B,但是像C这样简单的情况似乎很快变得复杂 我几乎可以肯定的是,我们不可能在所有情况下都静态求解x,这没关系。我想知道尝试它的策略,如何识别什么时候做不到。如果我们需要包含类级字段和多线程呢?闭包?如果我们知道对于X的所有可能值的集合X,|X |

在与以下每个示例类似的代码中,我希望能够静态分析代码,以确定传递到SpecialFunction()的可能值的列表

我已经可以将C#解析成一个抽象语法树,并且可以处理像A这样的情况,我想我可以跟踪值的初始赋值来猜测情况B,但是像C这样简单的情况似乎很快变得复杂

我几乎可以肯定的是,我们不可能在所有情况下都静态求解x,这没关系。我想知道尝试它的策略,如何识别什么时候做不到。如果我们需要包含类级字段和多线程呢?闭包?如果我们知道对于
X
的所有可能值的集合
X
|X |<50
,会有帮助吗


根据@Vladimir Perevalov的建议,如何将Pex中的概念应用于为目标代码点寻找可能的值(而不是Pex似乎在做什么,即发现导致未检查(?)异常情况的代码路径和值)?

您需要的是全局数据流分析(“什么值分配/副作用达到什么使用点”)[需要控制流分析作为先导]和某种范围分析(“总结可以达到某一点的一组值”)

计算数据流需要有一个完整的C#前端、本地控制和数据流分析,然后将这些答案拼接到全局数据流分析中

范围分析要求您首先定义如何对可能的值集进行编码;允许使用什么规格体系?最简单的,只是一组值,往往会爆炸。中间规格方案类似于OP的单一关系到常数,例如,“x<50”" . 任何这种有限方案的问题在于,值集的丰富性可能会导致您得到无用的答案,特别是如果存在其他感兴趣的谓词(如果x总是奇数,则单个关系到常量只能将其建模为“x<无穷大”)这显然是没有帮助的。因此,您希望选择一个足够复杂的规范方案,以对您感兴趣的各种值进行建模。但是,随着规范方案变得更加复杂,正确推断这些事实的机制变得更加复杂,因此您不能使其过于复杂

大多数可用的分析工具都没有这样的分析,更不用说向你展示了。PEX可能确实有这样的机制;如果你幸运的话,它也被展示了


我们有通用解析、符号表构建、控制/数据流分析,甚至范围分析机制(规范:x+1.不要认为这是一种“责任”静态分析猜测指定参数值范围的可能失败/成功,这很可能是
动态分析的“职责”。但即使如此,在这种情况下,您只处理几个参数,如果您处理一个函数,例如,
IEnumerableGetValuesForx(…)
?@Tigran-运行或模拟程序(或片段)这不是一个选项。而且,很明显,在某些情况下静态分析可以提供答案,而在某些情况下,静态分析显然无法提供答案。我正在尝试确定并实现它可以提供的情况。我能够与MSR Roslyn取得相当大的进展。我使用它就像解析AST一样,并且做了我自己的(有缺陷)推理不费吹灰之力。我认为Roslyn可以为我做更多的事情,但没有很好的文档记录。这足以证明概念。如果这个项目继续进行,我可能会向贵公司询问。我猜Roslyn很少做全局流分析。据我所知,C#主要是一个JIT编译器。JIT与glob有什么关系al flow analyzability?@Jason:1)如果你在进行JIT,将源代码转换为pCode(CIL)的工具(“C#编译器”,我认为Roslyn是)不需要编译高度优化的pCode,2)通常你会得到非常好的单独编译,这不利于全局优化。人们期望运行时JIT'er基于动态测量进行更复杂的分析;它可能有也可能没有全局优化,但它至少可以访问“整个”程序(模块动态加载的东西)。
SpecialFunction(5); // A

int x = 5;
SpecialFunction(x); // B

int x = 5;
x = condition ? 3 : 19;
SpecialFunction(x); // C