使用 Microsoft 登录
登录或创建帐户。
你好,
使用其他帐户。
你有多个帐户
选择要登录的帐户。

本文介绍了 Microsoft Visual Studio 2015年更新 3 个修复程序包。此修复程序包含 Visual C++ 优化程序和代码生成器 (c2.dll) 的几个修补程序。有关详细信息,请参阅"在此修补程序修复的问题"一节。

解决方案

如何获取此修复程序

下列文件已可从 Microsoft 下载中心下载:

Download 立即下载此修补程序包。

有关如何下载 Microsoft 支持文件的详细信息,请单击下面的文章编号,以查看 Microsoft 知识库中相应的文章:

119591如何从联机服务获得 Microsoft 支持文件Microsoft 已对此文件进行病毒扫描。Microsoft 使用自该文件发布日期起可用的最新的病毒检测软件。该文件存储在安全增强型服务器上,帮助防止对文件进行任何未经授权的更改。

系统必备组件

若要应用此修补程序,您必须安装的 Visual Studio 2015年更新 3。

重启要求

您可能需要重新启动计算机,如果正在使用的 Visual Studio 实例不在应用此修补程序后。

修补程序替换信息

此修补程序不替代其他修补程序。

此修补程序中修复的问题

此修补程序包含下列问题的修补程序:

  • 在优化程序修复一个错误,当提升循环之外的循环变量条件存储: #include <cstdlib> #include <cassert> struct Foo { int a; int b; }; int main() { Foo foo; foo.b = rand(); int a = rand(); int b = foo.b; for (int i = 0; i < 10; ++i) { int inner_b = b; int inner_a = a; if (inner_b < 0) // This gets incorrect hoisted outside the loop. // A workaround is /d2SSAOptimizer- { inner_a = 0; inner_b = 0; } if (inner_b >= 0) assert(inner_a == a); a += b; } return 0; }

     

  • 在优化器整数除法 bug 的修补程序: #include <stdio.h> volatile int z = 0; int main() { unsigned a, b; __int64 c; a = z; c = a; c = (c == 0) ? 1LL : c; b = (unsigned)((__int64)a * 100 / c); // Division was made unconditional // incorrectly creating a divide by zero. // A workaround is /d2SSAOptimizer- printf("%u\n", b); return 0; }

     

  • 在优化器整数除法 bug 的修补程序: int checkchecksum(int suly, int ell, int utkodert) { int x; ell -= utkodert; ell %= 103; if (suly - 1) utkodert /= (suly - 1); // Division was made unconditional, // incorrectly creating a potential divide by zero // A workaround is /d2SSAOptimizer- return utkodert; }

     

  • 在优化器整数除法 bug 的修补程序: typedef int unsigned uint; volatile uint out_index = 0; bool data[1] = {true}; bool __declspec(noinline) BugSSA(uint index) { uint group = index / 3; if (group == 0) // The division result being compared to zero is replaced // with a range check. We then incorrectly move the division { // to the next use of "group", without accounting for the fact // that "index" has changed. A workaround is /d2SSAOptimizer- return false; } index -= 3; group--; bool ret = data[group]; // crash here out_index = index; out_index = index; return ret; } int main() { volatile uint i = 3; return BugSSA(i); }

     

  • 修复的优化程序中出现崩溃 MIN_INT 除以-1: int test_div(bool flag, int dummy) { int result = std::numeric_limits<int>::min(); int other; if (flag) other = -1; else other = dummy - 1 - dummy; result /= other; // We would push the division up into both arms of the // if-then-else. One of those divisions would cause the // optimizer to evaluate MIN_INT/-1.This is a crash, similar // to dividing by zero. A workaround is /d2SSAOptimizer- return result; }

     

  • 优化程序中的修复程序的堆栈溢出: #include <stdio.h> // This example produced a stack overflow in the optimizer, which was // caused by mutually-recursive analysis functions not properly tracking // the number of times they were invocated. // A workaround is /d2SSAOptimizer- typedef unsigned char byte; typedef unsigned long long int uint64; int main() { const uint64 *sieveData = new uint64[1024]; uint64 bitIndexShift = 0; uint64 curSieveChunk = 0xfafd7bbef7ffffffULL & ~uint64(3); const unsigned int *NumbersCoprimeToModulo = new unsigned int[16]; const unsigned int *PossiblePrimesForModuloPtr = NumbersCoprimeToModulo; while (!curSieveChunk) { curSieveChunk = *(sieveData++); const uint64 NewValues = (16 << 8) | (32 << 24); bitIndexShift = (NewValues >> (bitIndexShift + 8)) & 255; PossiblePrimesForModuloPtr = NumbersCoprimeToModulo + bitIndexShift; } if (PossiblePrimesForModuloPtr - NumbersCoprimeToModulo != 0) { printf("fail"); return 1; } printf("pass"); return 0; }

     

  • 修复不正确的代码生成时删除冗余浮动点转换涉及将一个 int32 参数转换为 f64: #include <string> __declspec(noinline) void test(int Val) { double Val2 = Val; std::string Str; printf("%lld\n", __int64(Val2)); // We incorrectly try to read 64 bits of // floating point from the parameter area, // instead of reading 32 bits of integer // and converting it. A workaround is // to throw /d2SSAOptimizer- } int main() { test(6); test(7); return 0; }

     

  • 修复拆分流图节点在默认语句的 switch 块,有关更多详细信息,请参阅https://bugs.chromium.org/p/chromium/issues/detail?id=627216#c15时优化程序崩溃。

  • 在那里我们执行不正确的强度降低的无符号辅助归纳变量主要归纳变量的倍数在循环优化程序修复 bug: #include <assert.h> #include <malloc.h> #include <stdio.h> typedef unsigned int uint; typedef unsigned char byte; /* There is a corner case in the compiler's loop optimizer. The corner case arose if an induction variable (IV) is a multiple of the loop index, and there's a comparison of the IV to an integer that is less than this multiplication factor. A workaround is to use #pragma optimize("", off) / #pragma optimize("", on) around the affected function. */ int main(int argc, char *argv[]) { const uint w = 256; const uint h = 64; const uint w_new = w >> 1; const uint h_new = h >> 1; const byte *const src = (byte *)malloc(w * h); byte *it_out = (byte *)malloc(w_new * h_new); int fail = 0; for (uint y_new = 0; y_new < h_new; ++y_new) { for (uint x_new = 0; x_new < w_new; ++x_new, ++it_out) { uint x = x_new * 2; uint y = y_new * 2; if (x < 1 || y < 1) { *it_out = 0; continue; } if (x != 0) { } else { fail = 1; } *it_out = 4 * src[y * w + x]; } } if (fail) { printf("fail\n"); return (1); } printf("pass\n"); return (0); }

     

  • 为 C4883 提供了一种解决办法": 函数大小抑制优化"。当优化程序会看到巨大的函数时,它将执行的优化缩放回。它将 C4883 时发出警告它执行此操作,如果您已启用通过 /we4883 警告。如果您想要重写此决定取消优化,引发 /d2OptimizeHugeFunctions 开关。

  • 修复在 c2 编译器崩溃 !当您在 x64 上执行优化的 PpCanPropagateForward。

  • 对于涉及正确归纳变量强度降低的循环优化程序 bug 的修补程序。

  • 修复不正确重新排序的表达式,其中涉及读取和写入内存,因为别名错误检查。

  • 修复的寄存器分配器 bug,它涉及到编译器生成临时现有跨多个异常处理区域。

状态

Microsoft 已经确认这是“适用于”一节中列出的 Microsoft 产品中的问题。

需要更多帮助?

需要更多选项?

了解订阅权益、浏览培训课程、了解如何保护设备等。

社区可帮助你提出和回答问题、提供反馈,并听取经验丰富专家的意见。

此信息是否有帮助?

你对语言质量的满意程度如何?
哪些因素影响了你的体验?
按“提交”即表示你的反馈将用于改进 Microsoft 产品和服务。 你的 IT 管理员将能够收集此数据。 隐私声明。

谢谢您的反馈!

×