def test_switch_statement(self): source = """ { int a = 10, sum = 0; switch (10) { case 0: sum = -1; case 1: sum += 1; break; case 10: sum += 10; case 11: { sum += 1; case 15: sum += 1; } break; case 12: sum += 1; default: sum += 1; } a = sum; } """ self.evaluate(source) self.assert_base_element(ConstantExpression(12, IntegerType()))
def test_var_arg_function(self): code = """ #include <stdarg.h> struct temp {int i; struct {int v[10]; char c;} s;}; int foo(int initial, ...) { va_list values; va_start(values, initial); int a = va_arg(values, int); char c = va_arg(values, char); double d = va_arg(values, double); struct temp s = va_arg(values, struct temp); int last = va_arg(values, int); int *ptr = va_arg(values, int *); return a == -1 && c == 'c'&& d == 12.5 && s.i == 1 && s.s.c == 'f' && last == 10 && ptr == 10; } int main() { struct temp s = {1, .s = {.c = 'f'}}; return foo(0, -1, 'c', 12.5, s, 10, (int *)10); } """ self.evaluate(code) self.assert_base_element(ConstantExpression(1, IntegerType()))
def test_malloc_simple(self): source = """ #include <stdlib.h> #define TEST_SIZE 10 int main() { void *heap_ptr = sbrk(0); unsigned char *value = malloc(sizeof(unsigned char) * TEST_SIZE); unsigned int index = TEST_SIZE; unsigned char *temp = value; while (index--) *temp++ = 1 - TEST_SIZE; index = TEST_SIZE; temp = value; while (index--) if (*temp++ != (unsigned char)(1 - TEST_SIZE)) return -2; free(value); if (heap_ptr != sbrk(0)) return -1; return 0; } """ self.evaluate(source) self.assert_base_element(ConstantExpression(0, IntegerType()))
def test_strcpy(self): code = """ #include <string.h> int main() { int guard_0 = 0; char src[19] = "this is a test ..."; int guard_1 = 0; char dest[19] = {[0 ... 18] = 'g'}; int guard_2 = 0; strcpy(dest, ""); if (dest[0] != '\0') return -1; if (strcpy(dest, src) != dest) return -1; size_t index = 0; while (index < sizeof(src)/sizeof(src[0])) if (src[index] != dest[index++]) return -1; return !(guard_0 || guard_1 || guard_2); } """ self.evaluate(code) self.assert_base_element(ConstantExpression(1, IntegerType()))
def test_true_for_loop(self): source = """ { int index; for (index = 0; index < 10; index += 1); } """ self.evaluate(source) self.assert_base_element(ConstantExpression(10, IntegerType()))
def test_compound_addition(self): code = """ { int a = 10, b = 1; a += b; } """ self.evaluate(code) self.assert_base_element(ConstantExpression(11, IntegerType()))
def test_malloc_complex(self): source = """ #include <stdlib.h> #include <string.h> #include <stdio.h> #define TEST_SIZE 20 #define MAX_BLOCK_SIZE 256 struct __block_type__ {int size; char value; unsigned char *address;}; void randomly_initialize_block(struct __block_type__ *block) { block->size = (rand() & (MAX_BLOCK_SIZE - 1)); block->value = (char)rand(); block->address = malloc(block->size * sizeof(unsigned char)); memset(block->address, block->value, block->size * sizeof(unsigned char)); } int main() { void *initial_heap_pointer = sbrk(0); // record initial heap pointer ... struct __block_type__ allocated_blocks[TEST_SIZE]; int test_size = TEST_SIZE; size_t total_allocation_size = 0; while (test_size--) // randomly initialize all the blocks ... { randomly_initialize_block(&allocated_blocks[test_size]); total_allocation_size += allocated_blocks[test_size].size; } test_size = 2 * TEST_SIZE; int index; while (test_size--) // randomly deallocate some of the blocks ... { index = rand() % TEST_SIZE; // randomly pick a block ... free(allocated_blocks[index].address); // deallocate its content ... randomly_initialize_block(&allocated_blocks[index]); // randomly re-initialize its content ... } test_size = TEST_SIZE; while (test_size--) { // check that free/malloc haven't corrupted any other blocks ... for (index = 0; index < allocated_blocks[test_size].size; index++) if (allocated_blocks[test_size].address[index] != allocated_blocks[test_size].value) return -1; free(allocated_blocks[test_size].address); // check was ok, so deallocate it ... } return sbrk(0) - initial_heap_pointer; // check that deallocating everything has reset the heap pointer... } """ self.evaluate(source) self.assert_base_element(ConstantExpression(0, IntegerType())) # self.assertEqual(self.mem[self.cpu.stack_pointer], 0)
def test_false_while_loop(self): source = """ { int sum = 0; while (0) sum += 1; } """ self.evaluate(source) self.assert_base_element(ConstantExpression(0, IntegerType()))
def test_true_while_loop(self): source = """ { int sum = 0, index = 10; while (sum < index) sum += 1; } """ self.evaluate(source) self.assert_base_element(ConstantExpression(10, IntegerType()))
def test_ternary(self): code = ''' { int b = 11; int foo = b ? b += 2 : (foo += 3); b = b - foo; } ''' self.evaluate(code) self.assert_base_element(ConstantExpression(0, IntegerType()))
def test_pointer_subtraction_zero(self): code = """ { unsigned int size = -1; struct foo {double a; int b[10];} *a = (void *)sizeof(struct foo); size = a - 1; } """ self.evaluate(code) self.assert_base_element(ConstantExpression(0, IntegerType()))
def test_if_statement(self): source = """ { int a = 10; if (1) a = 0; } """ self.evaluate(source) self.assert_base_element(ConstantExpression(0, IntegerType()))
def test_ternary_false(self): code = ''' { int b = 0; int c = 1; int foo = b ? c += 1 : b; b = b + c + foo; } ''' self.evaluate(code) self.assert_base_element(ConstantExpression(1, IntegerType()))
def test_goto(self): source = """ { goto label; int index = 10; label: index = 1; } """ self.evaluate(source) self.assert_base_element(ConstantExpression(1, IntegerType()))
def test_global_initializer_and_postfix_increment(self): code = """ int values[2] = {0}; int main() { ++values[0]; return values[0]; } """ self.evaluate(code) self.assert_base_element(ConstantExpression(1, IntegerType()))
def test_compound_statement(self): source = """ { int a = 10; { int a1 = 1; } a = a; } """ super(TestCompoundStatement, self).evaluate(source) self.assert_base_element(ConstantExpression(10, IntegerType()))
def test_global_constant_initializer(self): code = """ struct {int a; char b; int c[10]; struct {int a; double c;} foo[10];} foo = {.a=10, .c[1] = -1, .foo[0 ... 2] = {-1, -1} }; int main() { return foo.a == 10 && foo.c[1] == -1 && foo.foo[0].a == -1 && foo.foo[1].c == -1 && foo.foo[3].c == 0; } """ self.evaluate(code) self.assert_base_element(ConstantExpression(1, IntegerType()))
def test_pointer_pointer_subtraction(self): code = """ { unsigned int index = 0; struct foo {double a; int b[10];} *a = (void *)0, *b = (void *)sizeof(struct foo); index = b - a; } """ self.evaluate(code) self.assert_base_element(ConstantExpression(1, IntegerType()))
def test_pointer_addition(self): code = """ { unsigned int offset = -1; struct foo {double a; int b[10];}; struct foo *a = (void *)0; a++; offset = (unsigned long long)a - sizeof(struct foo); } """ self.evaluate(code) self.assert_base_element(ConstantExpression(0, IntegerType()))
def test_break(self): source = """ { int sum = 0, index = 0; while (index < 10) { sum += 1; break ; } } """ self.evaluate(source) self.assert_base_element(ConstantExpression(1, IntegerType()))
def test_compound_for_loop(self): source = """ { int index = 10; for (; index; ) { int sum = 10; index -= 1; } } """ self.evaluate(source) self.assert_base_element(ConstantExpression(0, IntegerType()))
def test_global_union_initializer(self): code = """ union { unsigned long long a; double b; char c[20]; int d[0]; } foo = {.a=10, .b=10.5}; int main() { return foo.b == 10.5; } """ self.evaluate(code) self.assert_base_element(ConstantExpression(1, IntegerType())) # self.assertEqual(1, self.mem[self.cpu.stack_pointer])
def test_compound_while_loop(self): source = """ { int sum = 10, index = 0; while (index < 10) { int sum1 = 0; index += 1; sum1 = index; } } """ self.evaluate(source) self.assert_base_element(ConstantExpression(10, IntegerType()))
def test_memcmp_greater_than(self): code = """ #include <string.h> #define TEST_SIZE {test_size} int main() {{ int guard_0 = 0; int values[TEST_SIZE] = {{[0 ... TEST_SIZE/2] = 2, [TEST_SIZE/2 + 1 ... TEST_SIZE - 1] = 1}}; int guard_1 = 0; return memcmp(values, &values[TEST_SIZE/4], sizeof(values)/2) > 0; }} """.format(test_size=TestString.test_size) self.evaluate(code) self.assert_base_element(ConstantExpression(1, IntegerType()))
def test_definition(self): code = """ int a = 1; double b[100]; void foo(){} int main() { b[2] = 4; return b[2]; } """ self.evaluate(code) self.assert_base_element(ConstantExpression(4, IntegerType()))
def test_continue(self): source = """ { int sum = 0, index = 0; while (index < 10) { index += 1; continue ; sum += 1; } } """ self.evaluate(source) # self.assertEqual(int(self.mem[self.cpu.stack_pointer]), 0) self.assert_base_element(ConstantExpression(0, IntegerType()))