Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / compiler-rt / test / dfsan / conditional_callbacks.c
blob0183f0acc5dc6b138f5f420c59df8a18510463f6
1 // RUN: %clang_dfsan -fno-sanitize=dataflow -O2 -fPIE -DCALLBACKS -c %s -o %t-callbacks.o
2 // RUN: %clang_dfsan -fsanitize-ignorelist=%S/Inputs/flags_abilist.txt -O2 -mllvm -dfsan-conditional-callbacks %s %t-callbacks.o -o %t
3 // RUN: %run %t FooBarBaz 2>&1 | FileCheck %s
4 //
5 // RUN: %clang_dfsan -fno-sanitize=dataflow -O2 -fPIE -DCALLBACKS -DORIGINS -c %s -o %t-callbacks-orig.o
6 // RUN: %clang_dfsan -fsanitize-ignorelist=%S/Inputs/flags_abilist.txt -O2 -mllvm -dfsan-conditional-callbacks -mllvm -dfsan-track-origins=1 -DORIGINS %s %t-callbacks-orig.o -o %t-orig
7 // RUN: %run %t-orig FooBarBaz 2>&1 | FileCheck %s
9 // Tests that callbacks are inserted for conditionals when
10 // -dfsan-conditional-callbacks is specified.
12 #include <assert.h>
13 #include <sanitizer/dfsan_interface.h>
14 #include <stdio.h>
15 #include <string.h>
17 #ifdef CALLBACKS
18 // Compile this code without DFSan to avoid recursive instrumentation.
20 extern dfsan_label LabelI;
21 extern dfsan_label LabelJ;
22 extern dfsan_label LabelIJ;
24 void my_dfsan_conditional_callback(dfsan_label Label, dfsan_origin Origin) {
25 assert(Label != 0);
26 #ifdef ORIGINS
27 assert(Origin != 0);
28 #else
29 assert(Origin == 0);
30 #endif
32 static int Count = 0;
33 switch (Count++) {
34 case 0:
35 assert(Label == LabelI);
36 break;
37 case 1:
38 assert(Label == LabelJ);
39 break;
40 case 2:
41 assert(Label == LabelIJ);
42 break;
43 default:
44 break;
47 fprintf(stderr, "Label %u used as condition\n", Label);
50 #else
51 // Compile this code with DFSan and -dfsan-conditional-callbacks to insert the
52 // callbacks.
54 dfsan_label LabelI;
55 dfsan_label LabelJ;
56 dfsan_label LabelIJ;
58 extern void my_dfsan_conditional_callback(dfsan_label Label,
59 dfsan_origin Origin);
61 int main(int Argc, char *Argv[]) {
62 assert(Argc == 2);
64 dfsan_set_conditional_callback(my_dfsan_conditional_callback);
66 int result = 0;
67 // Make these not look like constants, otherwise the branch we're expecting
68 // may be optimized out.
69 int DataI = (Argv[0][0] != 0) ? 1 : 0;
70 int DataJ = (Argv[1][0] != 0) ? 2 : 0;
71 LabelI = 1;
72 dfsan_set_label(LabelI, &DataI, sizeof(DataI));
73 LabelJ = 2;
74 dfsan_set_label(LabelJ, &DataJ, sizeof(DataJ));
75 LabelIJ = dfsan_union(LabelI, LabelJ);
77 assert(dfsan_get_label(DataI) == LabelI);
79 // CHECK: Label 1 used as condition
80 if (DataI) {
81 result = 42;
84 fprintf(stderr, "Result is %d\n", result);
85 assert(dfsan_get_label(DataJ) == LabelJ);
87 // CHECK: Label 2 used as condition
88 switch (DataJ) {
89 case 1:
90 result += 10000;
91 break;
92 case 2:
93 result += 4200;
94 break;
95 default:
96 break;
99 int tainted_cond = ((DataI * DataJ) != 1);
100 fprintf(stderr, "Result is %d\n", result);
101 assert(dfsan_get_label(tainted_cond) == LabelIJ);
103 // CHECK: Label 3 used as condition
104 result = tainted_cond ? result + 420000 : 9;
106 fprintf(stderr, "Result is %d\n", result);
107 assert(result == 424242);
108 return 0;
111 #endif // #ifdef CALLBACKS