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