blob: b2e31ee09691f24342bf3324326a66664945ea01 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
// RUN: %clang %s -emit-llvm -g -c -o %t.bc
// RUN: rm -rf %t.klee-out
// RUN: %klee --search=bfs --output-dir=%t.klee-out --write-no-tests --exit-on-error %t.bc 2>&1 | FileCheck %s
#include "klee/klee.h"
#include <stdio.h>
void foo(const char *msg) { printf("foo: %s\n", msg); }
void baz(const char *msg) { printf("baz: %s\n", msg); }
void (*xx)(const char *) = foo;
void bar(void (*fp)(const char *)) { fp("called via bar"); }
int main(int argc, char **argv) {
void (*fp)(const char *) = foo;
printf("going to call through fp\n");
// CHECK: foo: called via fp
fp("called via fp");
printf("calling via pass through\n");
// CHECK: foo: called via bar
bar(foo);
fp = baz;
// CHECK: baz: called via fp
fp("called via fp");
// CHECK: foo: called via xx
xx("called via xx");
klee_make_symbolic(&fp, sizeof fp, "fp");
if(fp == baz) {
// CHECK: baz: calling via simple symbolic!
printf("fp = %p, baz = %p\n", fp, baz);
fp("calling via simple symbolic!");
return 0;
}
void (*fp2)(const char *);
klee_make_symbolic(&fp2, sizeof fp2, "fp2");
if(fp2 == baz || fp2 == foo) {
// CHECK: baz: calling via symbolic!
// CHECK: foo: calling via symbolic!
fp2("calling via symbolic!");
}
return 0;
}
|