about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
authorDan Liew <daniel.liew@imperial.ac.uk>2016-11-25 08:37:28 +0000
committerDan Liew <daniel.liew@imperial.ac.uk>2017-02-21 21:32:52 +0000
commit17705a0ecea3d5c6ad74587cc76adf92e6e8be6d (patch)
treef8993f979bc0b6e897badd8eb4946b86504bcc5c
parent8090de20463b4eff4f0397c3fa386c72eb4f0cad (diff)
downloadklee-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.c43
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