diff options
author | Dan Liew <daniel.liew@imperial.ac.uk> | 2016-11-25 08:37:28 +0000 |
---|---|---|
committer | Dan Liew <daniel.liew@imperial.ac.uk> | 2017-02-21 21:32:52 +0000 |
commit | 17705a0ecea3d5c6ad74587cc76adf92e6e8be6d (patch) | |
tree | f8993f979bc0b6e897badd8eb4946b86504bcc5c | |
parent | 8090de20463b4eff4f0397c3fa386c72eb4f0cad (diff) | |
download | klee-17705a0ecea3d5c6ad74587cc76adf92e6e8be6d.tar.gz |
Add test case that causes an assertion failure in `klee::getDirectCallTarget(llvm::CallSite)`.
The problem is that it doesn't handle bitcasted functions that call a weak alias.
-rw-r--r-- | test/regression/2016-11-24-bitcast-weak-alias.c | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/test/regression/2016-11-24-bitcast-weak-alias.c b/test/regression/2016-11-24-bitcast-weak-alias.c new file mode 100644 index 00000000..f115731b --- /dev/null +++ b/test/regression/2016-11-24-bitcast-weak-alias.c @@ -0,0 +1,43 @@ +// RUN: %llvmgcc %s -Wall -emit-llvm -g -O0 -c -o %t.bc +// RUN: rm -rf %t.klee-out +// RUN: klee --output-dir=%t.klee-out -exit-on-error -search=nurs:covnew %t.bc DUMMY_ARG >%t1.log 2>&1 +// RUN: FileCheck -input-file=%t1.log %s + +// This test case is designed to cover code in `klee::getDirectCallTarget(CallSite)`. +// In particular it designed to test the case where a bitcasted function call, calls +// a weak alias. +struct v1 { + int c; + int d; +}; + +int __real_function(struct v1 *unused, struct v1 *unused2, int unused3) { + return 0; +} + +struct v2 { + int e; + int f; +}; + +int alias_function(struct v1 *, struct v1 *, int) + __attribute__((weak, alias("__real_function"))); + +int main(int argc, char** argv) { + struct v2 local = { .e= 0, .f=0 }; + int choice = (argc == 1); + int number = 0; + + // FIXME: Drop the guard when llvm 2.9 is dropped. + // Prevent actually making the call at runtime due to llvm-gcc + // injecting an abort if the call is made. The call is guarded + // in such a way that the compiler cannot remove the call. + if (choice) { + // Call via a bitcasted alias. + number = ((int (*)(struct v2 *, struct v2 *, int))alias_function)( + &local, &local, 0); + } + return number % 255; +} + +// CHECK: KLEE: done: completed paths = 1 |