1 | // RUN: %clang_dfsan -DLIB -c %s -o %t.lib.o && \ |
2 | // RUN: %clang_dfsan -c %s -o %t.o && \ |
3 | // RUN: %clang_dfsan %t.lib.o %t.o -o %t.bin && \ |
4 | // RUN: %run %t.bin |
5 | |
6 | // RUN: %clang_dfsan -mllvm -dfsan-args-abi -DLIB -c %s -o %t.lib.o && \ |
7 | // RUN: %clang_dfsan -mllvm -dfsan-args-abi -c %s -o %t.o && \ |
8 | // RUN: %clang_dfsan -mllvm -dfsan-args-abi %t.o %t.lib.o -o %t.bin && \ |
9 | // RUN: %run %t.bin |
10 | // |
11 | // REQUIRES: x86_64-target-arch |
12 | |
13 | #include <sanitizer/dfsan_interface.h> |
14 | #include <assert.h> |
15 | |
16 | #ifdef LIB |
17 | // Compiling this file with and without LIB defined allows this file to be |
18 | // built as two separate translation units. This ensures that the code |
19 | // can not be optimized in a way that removes behavior we wish to test. For |
20 | // example, computing a value should cause labels to be allocated only if |
21 | // the computation is actually done. Putting the computation here prevents |
22 | // the compiler from optimizing away the computation (and labeling) that |
23 | // tests wish to verify. |
24 | |
25 | int add_in_separate_translation_unit(int a, int b) { |
26 | return a + b; |
27 | } |
28 | |
29 | int multiply_in_separate_translation_unit(int a, int b) { |
30 | return a * b; |
31 | } |
32 | |
33 | #else |
34 | |
35 | int add_in_separate_translation_unit(int i, int j); |
36 | int multiply_in_separate_translation_unit(int i, int j); |
37 | |
38 | int main(void) { |
39 | size_t label_count; |
40 | |
41 | // No labels allocated yet. |
42 | label_count = dfsan_get_label_count(); |
43 | assert(0 == label_count); |
44 | |
45 | int i = 1; |
46 | dfsan_label i_label = dfsan_create_label("i" , 0); |
47 | dfsan_set_label(i_label, &i, sizeof(i)); |
48 | |
49 | // One label allocated for i. |
50 | label_count = dfsan_get_label_count(); |
51 | assert(1u == label_count); |
52 | |
53 | int j = 2; |
54 | dfsan_label j_label = dfsan_create_label("j" , 0); |
55 | dfsan_set_label(j_label, &j, sizeof(j)); |
56 | |
57 | // Check that a new label was allocated for j. |
58 | label_count = dfsan_get_label_count(); |
59 | assert(2u == label_count); |
60 | |
61 | // Create a value that combines i and j. |
62 | int i_plus_j = add_in_separate_translation_unit(i, j); |
63 | |
64 | // Check that a label was created for the union of i and j. |
65 | label_count = dfsan_get_label_count(); |
66 | assert(3u == label_count); |
67 | |
68 | // Combine i and j in a different way. Check that the existing label is |
69 | // reused, and a new label is not created. |
70 | int j_times_i = multiply_in_separate_translation_unit(j, i); |
71 | label_count = dfsan_get_label_count(); |
72 | assert(3u == label_count); |
73 | assert(dfsan_get_label(i_plus_j) == dfsan_get_label(j_times_i)); |
74 | |
75 | return 0; |
76 | } |
77 | #endif // #ifdef LIB |
78 | |