tests/vg_regtest: Always evaluate prerequisite expressions with sh
[valgrind.git] / memcheck / tests / origin3-no.c
bloba8145fa8444d484864936e5a6ee2f947ae17861d
2 /* This test case was originally written by Nicholas Nethercote. */
4 // [[This comment applies to the old piggybacking approach to
5 // origin-tracking. The newer approach handles the cases in this file
6 // correctly.]]
7 // This test demonstrates cases the piggybacking algorithm cannot handle,
8 // but which are handled ok by the instrumentation based algorithm.
10 #include <assert.h>
11 #include <stdlib.h>
12 #include <stdio.h>
13 #include "../memcheck.h"
15 int x = 0;
17 __attribute__((noinline)) int t1(void);
18 __attribute__((noinline)) int t2(void);
19 __attribute__((noinline)) int t3(void);
20 __attribute__((noinline)) int t4(void);
21 __attribute__((noinline)) int t5(void);
22 __attribute__((noinline)) int t6(void);
24 int main(void)
26 assert(4 == sizeof(int));
28 x += t1();
29 x += t2();
30 x += t3();
31 x += t4();
32 x += t5();
33 x += t6();
35 return x & 255;
38 __attribute__((noinline)) int t1(void)
40 // 8-bit undefined value. When compared it's loaded from memory, so will
41 // never work.
42 char* ptr_to_undef_char = malloc(sizeof(char));
43 char undef_char = *ptr_to_undef_char;
44 fprintf(stderr, "\nUndef 1 of 8 (8 bit undef)\n");
45 return (undef_char == 0x12 ? 11 : 22);
48 __attribute__((noinline)) int t2(void)
50 // Stack, 8-bit from (recently) 32-bit. But the load only loads 8-bits
51 // of the value, so it'll never work.
52 int undef_stack_int;
53 register char undef_stack_char = (char)undef_stack_int;
54 fprintf(stderr, "\nUndef 2 of 8 (8 bits of 32 undef)\n");
55 return (undef_stack_char == 0x12 ? 11 : 22);
58 __attribute__((noinline)) int t3(void)
60 // 32-bit undefined value. This one is identified, and is here for
61 // sanity-checking.
62 int* ptr_to_undef_int = malloc(sizeof(int));
63 int undef_int = *ptr_to_undef_int;
64 fprintf(stderr, "\nUndef 3 of 8 (32 bit undef)\n");
65 return (undef_int == 0x12345678 ? 13 : 24);
68 __attribute__((noinline)) int t4(void)
70 // Unaligned 32-bit value.
71 int* ptr_to_undef_int = malloc(sizeof(int) + 1);
72 int undef_unaligned_int = *(int*)((long)ptr_to_undef_int + 1);
73 fprintf(stderr, "\nUndef 4 of 8 (32 bit undef, unaligned)\n");
74 return (undef_unaligned_int == 0x12345678 ? 14 : 25);
77 __attribute__((noinline)) int t5(void)
79 // Modified 32-bit value.
80 int* ptr_to_undef_int3 = malloc(sizeof(int));
81 int modified_undef_int = *ptr_to_undef_int3;
82 fprintf(stderr, "\nUndef 5 of 8 (32 bit undef, modified)\n");
83 modified_undef_int++;
84 return (modified_undef_int == 0x12345678 ? 15 : 26);
87 __attribute__((noinline)) int t6(void)
89 int y = 0;
91 // Uninitialised 32-bit value (middle of 3) is made undefined in two
92 // unaligned pieces:
93 // |....|....|....| three 4-byte integers
94 // XXXX-YY first MAKE_MEM_UNDEFINED
95 // YY-XXXX second MAKE_MEM_UNDEFINED
96 // Because the YY parts don't get marked (they're not 32-bit and aligned)
97 // the middle byte keeps its original value, which is zero (from calloc).
98 // So even though it's been marked as undefined, it doesn't have an
99 // origin-tracking value and so cannot be identified. We also check the
100 // first and third ints (which are identified) for sanity-checking.
102 int* ptr_to_3_undef_ints = calloc(3, sizeof(int));
103 int* ptr_to_middle = (int*)((long)ptr_to_3_undef_ints + 6);
104 (void) VALGRIND_MAKE_MEM_UNDEFINED(ptr_to_3_undef_ints, 6);
105 (void) VALGRIND_MAKE_MEM_UNDEFINED(ptr_to_middle, 6);
106 fprintf(stderr, "\nUndef 6 of 8 (32 bit undef, unaligned, strange, #1)\n");
107 y += (*(ptr_to_3_undef_ints + 0) == 0x12345678 ? 16 : 27);
108 fprintf(stderr, "\nUndef 7 of 8 (32 bit undef, unaligned, strange, #2)\n");
109 y += (*(ptr_to_3_undef_ints + 1) == 0x12345678 ? 17 : 28);
110 fprintf(stderr, "\nUndef 8 of 8 (32 bit undef, unaligned, strange, #3)\n");
111 y += (*(ptr_to_3_undef_ints + 2) == 0x12345678 ? 18 : 29);
112 return y;
115 return x;