Last active
August 20, 2017 17:56
-
-
Save uucidl/7a9dddd89a29354875d97575a90e8936 to your computer and use it in GitHub Desktop.
Reproduction of an optimizer bug with Visual Studio 2017
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Repro optimizer issue with Visual Studio 2017 */ | |
/* @language: c99 */ | |
/* | |
# Visual Studio 2015 (working) | |
-- | |
C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\bin\amd64\cl.exe | |
cl.exe -Fe:repro.exe repro.c -nologo -FC -EHsc -Z7 -Oi -GR- -Gm- -O2 -Z7 -W4 -WX -DEBUG | |
TEST repro.exe | |
Event layout: | |
int_count: [0x08,0x09) | |
int_values: [0x0c,0x18) | |
int_values[0]: [0x0c,0x10) | |
int_values[1]: [0x10,0x14) | |
--- | |
Event: | |
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | |
0x0000 20 00 00 00 00 00 00 00 01 CD CD CD 2A 00 00 00 | |
0x0010 CD CD CD CD CD CD CD CD | |
--- | |
exited with code 0 | |
0xCD is memory that wasn't touched. | |
int_count is 0x01 (1 argument) | |
int_values[0]: is 0x2A, which is our sentinel value | |
# Visual Studio 2017 (broken) | |
D:\Visual Studio 2017\VC\Tools\MSVC\14.10.25017\bin\HostX64\x64\cl.exe | |
cl.exe -Fe:repro.exe -nologo -FC -EHsc -Z7 -Oi -GR- -Gm- -O2 -Z7 -W4 -WX -DEBUG repro.c | |
TEST repro.exe | |
Event layout: | |
int_count: [0x08,0x09) | |
int_values: [0x0c,0x18) | |
int_values[0]: [0x0c,0x10) | |
int_values[1]: [0x10,0x14) | |
--- | |
Event: | |
00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f | |
0x0000 20 00 00 00 00 00 00 00 01 CD CD CD CD CD CD CD | |
0x0010 2A 00 00 00 CD CD CD CD | |
--- | |
Assertion failed: event->int_values[0] == 42, file repro.c, line 111 | |
ERROR: Test failed | |
exited with code -1073740791 | |
0xCD is memory that wasn't touched. | |
int_count is 0x01 (1 argument, correct) | |
int_values[0]: is 0xCD. Our sentinel value has been put instead at int_values[1]! | |
*/ | |
#include <assert.h> | |
#include <stddef.h> | |
#include <stdio.h> | |
struct SPDR_Event { | |
unsigned long long ts_ticks; | |
char int_count; | |
int int_values[3]; | |
}; | |
static int equal_zstring(char const* a, char const *b) { return strcmp(a, b) == 0; } | |
static void print_hexdump(unsigned char* bytes, size_t bytes_n, unsigned int offset_base); | |
int main(int argc, char** argv) | |
{ | |
(void) argc; | |
(void) argv; | |
/* print record layout */ { | |
printf("Event layout:\n"); | |
#define OP(m) printf("%20s: [0x%02x,0x%02x)\n", #m, \ | |
(unsigned int) offsetof(struct SPDR_Event, m), \ | |
(unsigned int) (offsetof(struct SPDR_Event, m) + \ | |
sizeof ((struct SPDR_Event*)0)->m)) | |
OP(int_count); | |
OP(int_values); | |
OP(int_values[0]); | |
OP(int_values[1]); | |
#undef OP | |
printf("---\n"); | |
fflush(stdout); | |
} | |
int clock_tick = 32; | |
struct SPDR_Event event_on_stack; | |
/* create event */ { | |
memset(&event_on_stack, 0xCD, sizeof event_on_stack); | |
{ | |
event_on_stack.ts_ticks = clock_tick++; | |
event_on_stack.int_count = 0; | |
} | |
{ | |
int i = event_on_stack.int_count++; | |
event_on_stack.int_values[i] = 42; | |
} | |
} | |
/* inspect event afterwards */ { | |
struct SPDR_Event* event = &event_on_stack; | |
printf("Event:\n"); | |
print_hexdump((unsigned char*)event, sizeof *event, 0); | |
printf("---\n"); | |
fflush(stdout); | |
assert(event->int_count == 1); | |
assert(event->int_values[0] == 42); | |
} | |
return 0; | |
} | |
static void print_hexdump(unsigned char* bytes, size_t bytes_n, unsigned int offset_base) | |
{ | |
unsigned char* bytes_l = bytes + bytes_n; | |
unsigned int row_offset = offset_base; | |
printf(" "); | |
{ | |
unsigned int n = 0; | |
while(n < 8) { | |
printf(" %02x", n); | |
++n; | |
} | |
printf(" "); | |
while(n < 16) { | |
printf(" %02x", n); | |
++n; | |
} | |
printf("\n"); | |
} | |
while (bytes != bytes_l) { | |
int n = 8; | |
printf("0x%04x", row_offset); | |
while (n-- && bytes != bytes_l) { | |
printf(" %02X", *bytes); ++bytes; | |
} | |
printf(" "); | |
n = 8; | |
while (n-- && bytes != bytes_l) { | |
printf(" %02X", *bytes); ++bytes; | |
} | |
printf ("\n"); | |
row_offset += 16; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
@uucidl: this has been fixed in the latest release, i.e. Visual Studio 2017 version 15.3.1 (released on August 18, 2017). I tried specifically with that compiler: