Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
e0c190bd
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
e0c190bd
编写于
3月 09, 2020
作者:
C
Charles Stoner
提交者:
GitHub
3月 09, 2020
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Constant folding for native integer values (#42143)
上级
9faacc48
变更
3
展开全部
隐藏空白更改
内联
并排
Showing
3 changed file
with
467 addition
and
6 deletion
+467
-6
src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs
src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs
+128
-6
src/Compilers/CSharp/Test/Semantic/Semantics/NativeIntegerTests.cs
...lers/CSharp/Test/Semantic/Semantics/NativeIntegerTests.cs
+336
-0
src/Compilers/Core/Portable/Compilation/Compilation.cs
src/Compilers/Core/Portable/Compilation/Compilation.cs
+3
-0
未找到文件。
src/Compilers/CSharp/Portable/Binder/Binder_Operators.cs
浏览文件 @
e0c190bd
...
...
@@ -1311,13 +1311,44 @@ private static object FoldDecimalBinaryOperators(BinaryOperatorKind kind, Consta
return
null
;
}
private
static
object
FoldNativeIntegerOverflowingBinaryOperator
(
BinaryOperatorKind
kind
,
ConstantValue
valueLeft
,
ConstantValue
valueRight
)
{
Debug
.
Assert
(
valueLeft
!=
null
);
Debug
.
Assert
(
valueRight
!=
null
);
checked
{
switch
(
kind
)
{
case
BinaryOperatorKind
.
NIntAddition
:
return
valueLeft
.
Int32Value
+
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
NUIntAddition
:
return
valueLeft
.
UInt32Value
+
valueRight
.
UInt32Value
;
case
BinaryOperatorKind
.
NIntSubtraction
:
return
valueLeft
.
Int32Value
-
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
NUIntSubtraction
:
return
valueLeft
.
UInt32Value
-
valueRight
.
UInt32Value
;
case
BinaryOperatorKind
.
NIntMultiplication
:
return
valueLeft
.
Int32Value
*
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
NUIntMultiplication
:
return
valueLeft
.
UInt32Value
*
valueRight
.
UInt32Value
;
case
BinaryOperatorKind
.
NIntDivision
:
return
valueLeft
.
Int32Value
/
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
NIntRemainder
:
return
valueLeft
.
Int32Value
%
valueRight
.
Int32Value
;
}
return
null
;
}
}
private
static
object
FoldUncheckedIntegralBinaryOperator
(
BinaryOperatorKind
kind
,
ConstantValue
valueLeft
,
ConstantValue
valueRight
)
{
Debug
.
Assert
(
valueLeft
!=
null
);
Debug
.
Assert
(
valueRight
!=
null
);
unchecked
{
Debug
.
Assert
(
valueLeft
!=
null
);
Debug
.
Assert
(
valueRight
!=
null
);
switch
(
kind
)
{
case
BinaryOperatorKind
.
IntAddition
:
...
...
@@ -1369,11 +1400,11 @@ private static object FoldUncheckedIntegralBinaryOperator(BinaryOperatorKind kin
private
static
object
FoldCheckedIntegralBinaryOperator
(
BinaryOperatorKind
kind
,
ConstantValue
valueLeft
,
ConstantValue
valueRight
)
{
Debug
.
Assert
(
valueLeft
!=
null
);
Debug
.
Assert
(
valueRight
!=
null
);
checked
{
Debug
.
Assert
(
valueLeft
!=
null
);
Debug
.
Assert
(
valueRight
!=
null
);
switch
(
kind
)
{
case
BinaryOperatorKind
.
IntAddition
:
...
...
@@ -1623,6 +1654,28 @@ internal static SpecialType GetEnumPromotedType(SpecialType underlyingType)
return
ConstantValue
.
Create
(
newValue
,
resultType
);
}
try
{
newValue
=
FoldNativeIntegerOverflowingBinaryOperator
(
kind
,
valueLeft
,
valueRight
);
}
catch
(
OverflowException
)
{
if
(
CheckOverflowAtCompileTime
)
{
Error
(
diagnostics
,
ErrorCode
.
ERR_CheckedOverflow
,
syntax
);
return
ConstantValue
.
Bad
;
}
else
{
return
null
;
}
}
if
(
newValue
!=
null
)
{
return
ConstantValue
.
Create
(
newValue
,
resultType
);
}
if
(
CheckOverflowAtCompileTime
)
{
try
...
...
@@ -1741,48 +1794,58 @@ private static object FoldNeverOverflowBinaryOperators(BinaryOperatorKind kind,
case
BinaryOperatorKind
.
FloatRemainder
:
return
valueLeft
.
SingleValue
%
valueRight
.
SingleValue
;
case
BinaryOperatorKind
.
IntLeftShift
:
case
BinaryOperatorKind
.
NIntLeftShift
:
return
valueLeft
.
Int32Value
<<
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
LongLeftShift
:
return
valueLeft
.
Int64Value
<<
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
UIntLeftShift
:
case
BinaryOperatorKind
.
NUIntLeftShift
:
return
valueLeft
.
UInt32Value
<<
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
ULongLeftShift
:
return
valueLeft
.
UInt64Value
<<
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
IntRightShift
:
case
BinaryOperatorKind
.
NIntRightShift
:
return
valueLeft
.
Int32Value
>>
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
LongRightShift
:
return
valueLeft
.
Int64Value
>>
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
UIntRightShift
:
case
BinaryOperatorKind
.
NUIntRightShift
:
return
valueLeft
.
UInt32Value
>>
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
ULongRightShift
:
return
valueLeft
.
UInt64Value
>>
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
BoolAnd
:
return
valueLeft
.
BooleanValue
&
valueRight
.
BooleanValue
;
case
BinaryOperatorKind
.
IntAnd
:
case
BinaryOperatorKind
.
NIntAnd
:
return
valueLeft
.
Int32Value
&
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
LongAnd
:
return
valueLeft
.
Int64Value
&
valueRight
.
Int64Value
;
case
BinaryOperatorKind
.
UIntAnd
:
case
BinaryOperatorKind
.
NUIntAnd
:
return
valueLeft
.
UInt32Value
&
valueRight
.
UInt32Value
;
case
BinaryOperatorKind
.
ULongAnd
:
return
valueLeft
.
UInt64Value
&
valueRight
.
UInt64Value
;
case
BinaryOperatorKind
.
BoolOr
:
return
valueLeft
.
BooleanValue
|
valueRight
.
BooleanValue
;
case
BinaryOperatorKind
.
IntOr
:
case
BinaryOperatorKind
.
NIntOr
:
return
valueLeft
.
Int32Value
|
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
LongOr
:
return
valueLeft
.
Int64Value
|
valueRight
.
Int64Value
;
case
BinaryOperatorKind
.
UIntOr
:
case
BinaryOperatorKind
.
NUIntOr
:
return
valueLeft
.
UInt32Value
|
valueRight
.
UInt32Value
;
case
BinaryOperatorKind
.
ULongOr
:
return
valueLeft
.
UInt64Value
|
valueRight
.
UInt64Value
;
case
BinaryOperatorKind
.
BoolXor
:
return
valueLeft
.
BooleanValue
^
valueRight
.
BooleanValue
;
case
BinaryOperatorKind
.
IntXor
:
case
BinaryOperatorKind
.
NIntXor
:
return
valueLeft
.
Int32Value
^
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
LongXor
:
return
valueLeft
.
Int64Value
^
valueRight
.
Int64Value
;
case
BinaryOperatorKind
.
UIntXor
:
case
BinaryOperatorKind
.
NUIntXor
:
return
valueLeft
.
UInt32Value
^
valueRight
.
UInt32Value
;
case
BinaryOperatorKind
.
ULongXor
:
return
valueLeft
.
UInt64Value
^
valueRight
.
UInt64Value
;
...
...
@@ -1801,10 +1864,12 @@ private static object FoldNeverOverflowBinaryOperators(BinaryOperatorKind kind,
case
BinaryOperatorKind
.
DoubleEqual
:
return
valueLeft
.
DoubleValue
==
valueRight
.
DoubleValue
;
case
BinaryOperatorKind
.
IntEqual
:
case
BinaryOperatorKind
.
NIntEqual
:
return
valueLeft
.
Int32Value
==
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
LongEqual
:
return
valueLeft
.
Int64Value
==
valueRight
.
Int64Value
;
case
BinaryOperatorKind
.
UIntEqual
:
case
BinaryOperatorKind
.
NUIntEqual
:
return
valueLeft
.
UInt32Value
==
valueRight
.
UInt32Value
;
case
BinaryOperatorKind
.
ULongEqual
:
return
valueLeft
.
UInt64Value
==
valueRight
.
UInt64Value
;
...
...
@@ -1819,10 +1884,12 @@ private static object FoldNeverOverflowBinaryOperators(BinaryOperatorKind kind,
case
BinaryOperatorKind
.
DoubleNotEqual
:
return
valueLeft
.
DoubleValue
!=
valueRight
.
DoubleValue
;
case
BinaryOperatorKind
.
IntNotEqual
:
case
BinaryOperatorKind
.
NIntNotEqual
:
return
valueLeft
.
Int32Value
!=
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
LongNotEqual
:
return
valueLeft
.
Int64Value
!=
valueRight
.
Int64Value
;
case
BinaryOperatorKind
.
UIntNotEqual
:
case
BinaryOperatorKind
.
NUIntNotEqual
:
return
valueLeft
.
UInt32Value
!=
valueRight
.
UInt32Value
;
case
BinaryOperatorKind
.
ULongNotEqual
:
return
valueLeft
.
UInt64Value
!=
valueRight
.
UInt64Value
;
...
...
@@ -1833,10 +1900,12 @@ private static object FoldNeverOverflowBinaryOperators(BinaryOperatorKind kind,
case
BinaryOperatorKind
.
DoubleLessThan
:
return
valueLeft
.
DoubleValue
<
valueRight
.
DoubleValue
;
case
BinaryOperatorKind
.
IntLessThan
:
case
BinaryOperatorKind
.
NIntLessThan
:
return
valueLeft
.
Int32Value
<
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
LongLessThan
:
return
valueLeft
.
Int64Value
<
valueRight
.
Int64Value
;
case
BinaryOperatorKind
.
UIntLessThan
:
case
BinaryOperatorKind
.
NUIntLessThan
:
return
valueLeft
.
UInt32Value
<
valueRight
.
UInt32Value
;
case
BinaryOperatorKind
.
ULongLessThan
:
return
valueLeft
.
UInt64Value
<
valueRight
.
UInt64Value
;
...
...
@@ -1847,10 +1916,12 @@ private static object FoldNeverOverflowBinaryOperators(BinaryOperatorKind kind,
case
BinaryOperatorKind
.
DoubleGreaterThan
:
return
valueLeft
.
DoubleValue
>
valueRight
.
DoubleValue
;
case
BinaryOperatorKind
.
IntGreaterThan
:
case
BinaryOperatorKind
.
NIntGreaterThan
:
return
valueLeft
.
Int32Value
>
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
LongGreaterThan
:
return
valueLeft
.
Int64Value
>
valueRight
.
Int64Value
;
case
BinaryOperatorKind
.
UIntGreaterThan
:
case
BinaryOperatorKind
.
NUIntGreaterThan
:
return
valueLeft
.
UInt32Value
>
valueRight
.
UInt32Value
;
case
BinaryOperatorKind
.
ULongGreaterThan
:
return
valueLeft
.
UInt64Value
>
valueRight
.
UInt64Value
;
...
...
@@ -1861,10 +1932,12 @@ private static object FoldNeverOverflowBinaryOperators(BinaryOperatorKind kind,
case
BinaryOperatorKind
.
DoubleLessThanOrEqual
:
return
valueLeft
.
DoubleValue
<=
valueRight
.
DoubleValue
;
case
BinaryOperatorKind
.
IntLessThanOrEqual
:
case
BinaryOperatorKind
.
NIntLessThanOrEqual
:
return
valueLeft
.
Int32Value
<=
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
LongLessThanOrEqual
:
return
valueLeft
.
Int64Value
<=
valueRight
.
Int64Value
;
case
BinaryOperatorKind
.
UIntLessThanOrEqual
:
case
BinaryOperatorKind
.
NUIntLessThanOrEqual
:
return
valueLeft
.
UInt32Value
<=
valueRight
.
UInt32Value
;
case
BinaryOperatorKind
.
ULongLessThanOrEqual
:
return
valueLeft
.
UInt64Value
<=
valueRight
.
UInt64Value
;
...
...
@@ -1875,14 +1948,17 @@ private static object FoldNeverOverflowBinaryOperators(BinaryOperatorKind kind,
case
BinaryOperatorKind
.
DoubleGreaterThanOrEqual
:
return
valueLeft
.
DoubleValue
>=
valueRight
.
DoubleValue
;
case
BinaryOperatorKind
.
IntGreaterThanOrEqual
:
case
BinaryOperatorKind
.
NIntGreaterThanOrEqual
:
return
valueLeft
.
Int32Value
>=
valueRight
.
Int32Value
;
case
BinaryOperatorKind
.
LongGreaterThanOrEqual
:
return
valueLeft
.
Int64Value
>=
valueRight
.
Int64Value
;
case
BinaryOperatorKind
.
UIntGreaterThanOrEqual
:
case
BinaryOperatorKind
.
NUIntGreaterThanOrEqual
:
return
valueLeft
.
UInt32Value
>=
valueRight
.
UInt32Value
;
case
BinaryOperatorKind
.
ULongGreaterThanOrEqual
:
return
valueLeft
.
UInt64Value
>=
valueRight
.
UInt64Value
;
case
BinaryOperatorKind
.
UIntDivision
:
case
BinaryOperatorKind
.
NUIntDivision
:
return
valueLeft
.
UInt32Value
/
valueRight
.
UInt32Value
;
case
BinaryOperatorKind
.
ULongDivision
:
return
valueLeft
.
UInt64Value
/
valueRight
.
UInt64Value
;
...
...
@@ -1893,6 +1969,7 @@ private static object FoldNeverOverflowBinaryOperators(BinaryOperatorKind kind,
case
BinaryOperatorKind
.
LongRemainder
:
return
(
valueRight
.
Int64Value
!=
-
1
)
?
valueLeft
.
Int64Value
%
valueRight
.
Int64Value
:
0
;
case
BinaryOperatorKind
.
UIntRemainder
:
case
BinaryOperatorKind
.
NUIntRemainder
:
return
valueLeft
.
UInt32Value
%
valueRight
.
UInt32Value
;
case
BinaryOperatorKind
.
ULongRemainder
:
return
valueLeft
.
UInt64Value
%
valueRight
.
UInt64Value
;
...
...
@@ -2464,6 +2541,28 @@ private BoundExpression BindUnaryOperatorCore(CSharpSyntaxNode node, string oper
return
ConstantValue
.
Create
(
newValue
,
resultType
);
}
try
{
newValue
=
FoldNativeIntegerOverflowingUnaryOperator
(
kind
,
value
);
}
catch
(
OverflowException
)
{
if
(
CheckOverflowAtCompileTime
)
{
Error
(
diagnostics
,
ErrorCode
.
ERR_CheckedOverflow
,
syntax
);
return
ConstantValue
.
Bad
;
}
else
{
return
null
;
}
}
if
(
newValue
!=
null
)
{
return
ConstantValue
.
Create
(
newValue
,
resultType
);
}
if
(
CheckOverflowAtCompileTime
)
{
try
...
...
@@ -2509,8 +2608,10 @@ private static object FoldNeverOverflowUnaryOperator(UnaryOperatorKind kind, Con
case
UnaryOperatorKind
.
ULongUnaryPlus
:
return
+
value
.
UInt64Value
;
case
UnaryOperatorKind
.
IntUnaryPlus
:
case
UnaryOperatorKind
.
NIntUnaryPlus
:
return
+
value
.
Int32Value
;
case
UnaryOperatorKind
.
UIntUnaryPlus
:
case
UnaryOperatorKind
.
NUIntUnaryPlus
:
return
+
value
.
UInt32Value
;
case
UnaryOperatorKind
.
BoolLogicalNegation
:
return
!
value
.
BooleanValue
;
...
...
@@ -2559,6 +2660,23 @@ private static object FoldCheckedIntegralUnaryOperator(UnaryOperatorKind kind, C
return
null
;
}
private
static
object
FoldNativeIntegerOverflowingUnaryOperator
(
UnaryOperatorKind
kind
,
ConstantValue
value
)
{
checked
{
switch
(
kind
)
{
case
UnaryOperatorKind
.
NIntUnaryMinus
:
return
-
value
.
Int32Value
;
case
UnaryOperatorKind
.
NIntBitwiseComplement
:
case
UnaryOperatorKind
.
NUIntBitwiseComplement
:
return
null
;
}
}
return
null
;
}
private
static
UnaryOperatorKind
SyntaxKindToUnaryOperatorKind
(
SyntaxKind
kind
)
{
switch
(
kind
)
...
...
@@ -2685,12 +2803,16 @@ private static bool IsDivisionByZero(BinaryOperatorKind kind, ConstantValue valu
return
valueRight
.
DecimalValue
==
0.0
m
;
case
BinaryOperatorKind
.
IntDivision
:
case
BinaryOperatorKind
.
IntRemainder
:
case
BinaryOperatorKind
.
NIntDivision
:
case
BinaryOperatorKind
.
NIntRemainder
:
return
valueRight
.
Int32Value
==
0
;
case
BinaryOperatorKind
.
LongDivision
:
case
BinaryOperatorKind
.
LongRemainder
:
return
valueRight
.
Int64Value
==
0
;
case
BinaryOperatorKind
.
UIntDivision
:
case
BinaryOperatorKind
.
UIntRemainder
:
case
BinaryOperatorKind
.
NUIntDivision
:
case
BinaryOperatorKind
.
NUIntRemainder
:
return
valueRight
.
UInt32Value
==
0
;
case
BinaryOperatorKind
.
ULongDivision
:
case
BinaryOperatorKind
.
ULongRemainder
:
...
...
src/Compilers/CSharp/Test/Semantic/Semantics/NativeIntegerTests.cs
浏览文件 @
e0c190bd
此差异已折叠。
点击以展开。
src/Compilers/Core/Portable/Compilation/Compilation.cs
浏览文件 @
e0c190bd
...
...
@@ -850,6 +850,7 @@ public INamedTypeSymbol GetSpecialType(SpecialType specialType)
/// <summary>
/// The TypeSymbol for the type 'dynamic' in this Compilation.
/// </summary>
/// <exception cref="NotSupportedException">If the compilation is a VisualBasic compilation.</exception>
public
ITypeSymbol
DynamicType
{
get
{
return
CommonDynamicType
;
}
}
protected
abstract
ITypeSymbol
CommonDynamicType
{
get
;
}
...
...
@@ -930,6 +931,7 @@ public IArrayTypeSymbol CreateArrayTypeSymbol(ITypeSymbol elementType, int rank)
/// Returns a new PointerTypeSymbol representing a pointer type tied to a type in this
/// Compilation.
/// </summary>
/// <exception cref="NotSupportedException">If the compilation is a VisualBasic compilation.</exception>
public
IPointerTypeSymbol
CreatePointerTypeSymbol
(
ITypeSymbol
pointedAtType
)
{
return
CommonCreatePointerTypeSymbol
(
pointedAtType
);
...
...
@@ -940,6 +942,7 @@ public IPointerTypeSymbol CreatePointerTypeSymbol(ITypeSymbol pointedAtType)
/// <summary>
/// Returns a new INamedTypeSymbol representing a native integer.
/// </summary>
/// <exception cref="NotSupportedException">If the compilation is a VisualBasic compilation.</exception>
public
INamedTypeSymbol
CreateNativeIntegerTypeSymbol
(
bool
signed
)
{
return
CommonCreateNativeIntegerTypeSymbol
(
signed
);
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录