1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown/* This test case was originally written by Nicholas Nethercote. */ 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// This test demonstrates some cases that the piggybacking algorithm 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// doesn't handle but conceivably might, with more modifications. 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown// The instrumentation based algorithm handles them ok, though. 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <assert.h> 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h> 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h> 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint x = 0; 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Browntypedef long long Long; 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline)) int t1(void); 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline)) int t2(void); 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline)) int t3(void); 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main(void) 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown assert(4 == sizeof(int)); 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown assert(8 == sizeof(Long)); 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown x += t1(); 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown x += t2(); 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown x += t3(); 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return x & 255; 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline)) int t1(void) 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 64-bit undefined double. 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown double* ptr_to_undef_double = malloc(sizeof(double)); 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown double undef_double = *ptr_to_undef_double; 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fprintf(stderr, "\nUndef 1 of 3 (64-bit FP)\n"); 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (undef_double < (double)123.45 ? 12 : 23); 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline)) int t2(void) 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // 32-bit undefined float. 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown float* ptr_to_undef_float = malloc(sizeof(float)); 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown float undef_float = *ptr_to_undef_float; 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fprintf(stderr, "\nUndef 2 of 3 (32-bit FP)\n"); 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (undef_float < (float)234.56 ? 13 : 24); 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown__attribute__((noinline)) int t3(void) 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Stack, 32-bit, recently modified. 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Problem here is that we don't chase backwards through loads and 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // stores. Ie. the variable is stored after it's been modified, then 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // loaded again, so we don't see the unmodified version. 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown int modified_undef_stack_int; 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown modified_undef_stack_int++; 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown fprintf(stderr, "\nUndef 3 of 3 (int)\n"); 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return (modified_undef_stack_int == 0x1234 ? 11 : 22); 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 61