Created
June 16, 2018 21:33
-
-
Save kssreeram/623eca83060532b232d97ed0ea27a5b5 to your computer and use it in GitHub Desktop.
Bug in Clang
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
/* | |
This program triggers a bug in Clang when compiling with optimizations. | |
When compiling with no-optimizations, the correct output is produced. | |
$ clang -O0 test-bug.c && ./a.out | |
value = 1 | |
When compiling with optimizations (-O2 or -O3), the output is wrong. | |
$ clang -O3 test-bug.c && ./a.out | |
value = 0 | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
// | |
// Helpers | |
// | |
typedef ssize_t Int; | |
typedef struct { | |
char *begin; | |
char *end; | |
} String; | |
String make_string(char *ptr, Int n) { | |
String s = { ptr, ptr+n }; | |
return s; | |
} | |
Int string_size(String s) { | |
return s.end - s.begin; | |
} | |
String c_string(char *s) { | |
return make_string(s, (Int)strlen(s)); | |
} | |
String alloc_string(String s) { | |
Int n = string_size(s); | |
char *ptr = malloc(n); | |
memcpy(ptr, s.begin, n); | |
return make_string(ptr, n); | |
} | |
void free_string(String s) { | |
free(s.begin); | |
} | |
// | |
// count_py_files | |
// | |
int are_strings_equal(String a, String b) { | |
if (string_size(a) != string_size(b)) { return 0; } | |
char *a_ptr = a.begin; | |
char *b_ptr = b.begin; | |
while (1) { | |
if (a_ptr == a.end) { break; } | |
if (*a_ptr != *b_ptr) { return 0; } | |
a_ptr += 1; | |
b_ptr += 1; | |
} | |
return 1; | |
} | |
int ends_with(String a, String b) { | |
Int na = string_size(a); | |
Int nb = string_size(b); | |
if (nb > na) { return 0; } | |
String tmp = make_string(a.begin + (na-nb), nb); | |
return are_strings_equal(tmp, b); | |
} | |
__attribute__((noinline)) | |
Int count_py_files(String *files_begin, String *files_end) { | |
String suffix = c_string(".py"); | |
Int n = 0; | |
String *files_ptr = files_begin; | |
while (files_ptr != files_end) { | |
if (ends_with(*files_ptr, suffix)) { | |
n += 1; | |
} | |
files_ptr += 1; | |
} | |
return n; | |
} | |
// | |
// main | |
// | |
int main() { | |
String file = alloc_string(c_string("foo.py")); | |
String *files_begin = &file; | |
String *files_end = files_begin + 1; | |
Int n = count_py_files(files_begin, files_end); | |
free_string(file); | |
printf("value = %d\n", (int)n); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment