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