Skip to content

Instantly share code, notes, and snippets.

@kssreeram
Created June 16, 2018 21:33
Show Gist options
  • Save kssreeram/623eca83060532b232d97ed0ea27a5b5 to your computer and use it in GitHub Desktop.
Save kssreeram/623eca83060532b232d97ed0ea27a5b5 to your computer and use it in GitHub Desktop.
Bug in Clang
/*
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