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