about summary refs log tree commit diff homepage
path: root/test/Feature
diff options
context:
space:
mode:
authorDaniel Dunbar <daniel@zuster.org>2009-05-21 04:36:41 +0000
committerDaniel Dunbar <daniel@zuster.org>2009-05-21 04:36:41 +0000
commit6f290d8f9e9d7faac295cb51fc96884a18f4ded4 (patch)
tree46e7d426abc0c9f06ac472ac6f7f9e661b5d78cb /test/Feature
parenta55960edd4dcd7535526de8d2277642522aa0209 (diff)
downloadklee-6f290d8f9e9d7faac295cb51fc96884a18f4ded4.tar.gz
Initial KLEE checkin.
 - Lots more tweaks, documentation, and web page content is needed,
   but this should compile & work on OS X & Linux.


git-svn-id: https://llvm.org/svn/llvm-project/klee/trunk@72205 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/Feature')
-rw-r--r--test/Feature/Alias.c25
-rw-r--r--test/Feature/AliasFunction.c33
-rw-r--r--test/Feature/AliasFunctionExit.c30
-rw-r--r--test/Feature/AsmAddresses.c22
-rw-r--r--test/Feature/ByteSwap.c16
-rw-r--r--test/Feature/CallToUndefinedExternal.cpp11
-rw-r--r--test/Feature/CheckForImpliedValue.c.failing23
-rw-r--r--test/Feature/CheckMemoryAccess.c26
-rw-r--r--test/Feature/CopyOnWrite.c26
-rw-r--r--test/Feature/DanglingConcreteReadExpr.c22
-rw-r--r--test/Feature/DefineFixedObject.c17
-rw-r--r--test/Feature/DoubleFree.c10
-rw-r--r--test/Feature/DumpStatesOnHalt.c8
-rw-r--r--test/Feature/Envp.c18
-rw-r--r--test/Feature/ExprLogging.c43
-rw-r--r--test/Feature/ExternalWeakLinkage.c11
-rw-r--r--test/Feature/FunctionPointer.c36
-rw-r--r--test/Feature/GetValue.c17
-rw-r--r--test/Feature/ImpliedValue.c.failing147
-rw-r--r--test/Feature/InAndOutOfBounds.c19
-rw-r--r--test/Feature/IndirectCallToBuiltin.c15
-rw-r--r--test/Feature/IndirectCallToExternal.c15
-rw-r--r--test/Feature/InvalidBitfieldAccess.c.failing28
-rw-r--r--test/Feature/IsSymbolic.c16
-rw-r--r--test/Feature/KleeReportError.c23
-rw-r--r--test/Feature/LongDoubleSupport.c20
-rw-r--r--test/Feature/LowerSwitch.c30
-rw-r--r--test/Feature/MakeConcreteSymbolic.c19
-rw-r--r--test/Feature/MakeSymbolicName.c17
-rw-r--r--test/Feature/MemoryLimit.c37
-rw-r--r--test/Feature/MultipleFreeResolution.c39
-rw-r--r--test/Feature/MultipleReadResolution.c43
-rw-r--r--test/Feature/MultipleReallocResolution.c63
-rw-r--r--test/Feature/MultipleWriteResolution.c43
-rw-r--r--test/Feature/NamedSeedMatching.c41
-rw-r--r--test/Feature/OneFreeError.c10
-rw-r--r--test/Feature/OneOutOfBounds.c10
-rw-r--r--test/Feature/Optimize.c22
-rw-r--r--test/Feature/OverlappedError.c19
-rw-r--r--test/Feature/PreferCex.c18
-rw-r--r--test/Feature/RaiseAsm.c39
-rw-r--r--test/Feature/ReallocFailure.c18
-rw-r--r--test/Feature/ReplayPath.c27
-rw-r--r--test/Feature/Searchers.c52
-rw-r--r--test/Feature/SetForking.c28
-rw-r--r--test/Feature/Vararg.c82
-rw-r--r--test/Feature/WithLibc.c22
-rw-r--r--test/Feature/WriteCov.c15
-rw-r--r--test/Feature/_utils._ll71
-rw-r--r--test/Feature/const_array_opt1.c37
-rw-r--r--test/Feature/dg.exp3
-rw-r--r--test/Feature/utils.h16
52 files changed, 1498 insertions, 0 deletions
diff --git a/test/Feature/Alias.c b/test/Feature/Alias.c
new file mode 100644
index 00000000..9300e2c7
--- /dev/null
+++ b/test/Feature/Alias.c
@@ -0,0 +1,25 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+// Darwin does not have strong aliases.
+// XFAIL: darwin
+
+#include <assert.h>
+
+// alias for global
+int b = 52;
+extern int a __attribute__((alias("b")));
+
+// alias for function
+int __foo() { return 52; }
+extern int foo() __attribute__((alias("__foo")));
+
+int *c = &a;
+
+int main() { 
+  assert(a == 52);
+  assert(foo() == 52);
+  assert(*c == 52);
+  
+  return 0;
+}
diff --git a/test/Feature/AliasFunction.c b/test/Feature/AliasFunction.c
new file mode 100644
index 00000000..e7acfc19
--- /dev/null
+++ b/test/Feature/AliasFunction.c
@@ -0,0 +1,33 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc > %t1.log
+// RUN: grep -c foo %t1.log | grep 5
+// RUN: grep -c bar %t1.log | grep 3
+
+#include <stdio.h>
+#include <stdlib.h>
+
+void foo() { printf("  foo()\n"); }
+void bar() { printf("  bar()\n"); }
+
+int main() {
+  int x;
+  klee_make_symbolic_name(&x, sizeof(x), "x");
+
+  // no aliases
+  foo();
+
+  if (x > 10)
+  {
+    // foo -> bar
+    klee_alias_function("foo", "bar");    
+
+    if (x > 20)
+      foo();
+  }
+  
+  foo();
+
+  // undo
+  klee_alias_function("foo", "foo");
+  foo();
+}
diff --git a/test/Feature/AliasFunctionExit.c b/test/Feature/AliasFunctionExit.c
new file mode 100644
index 00000000..fcaf7e6c
--- /dev/null
+++ b/test/Feature/AliasFunctionExit.c
@@ -0,0 +1,30 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc > %t1.log
+// RUN: grep -c START %t1.log | grep 1
+// RUN: grep -c END %t1.log | grep 2
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+void start(int x) {
+  printf("START\n");
+  if (x == 53)
+    exit(1);
+}
+
+void end(int status) {
+  klee_alias_function("exit", "exit");
+  printf("END: status = %d\n", status);
+  exit(status);
+}
+
+
+int main() {
+  int x;
+  klee_make_symbolic_name(&x, sizeof(x), "x");
+
+  klee_alias_function("exit", "end");
+  start(x);
+  end(0);
+}
diff --git a/test/Feature/AsmAddresses.c b/test/Feature/AsmAddresses.c
new file mode 100644
index 00000000..a58fc059
--- /dev/null
+++ b/test/Feature/AsmAddresses.c
@@ -0,0 +1,22 @@
+// RUN: %llvmgcc -g -c -o %t.bc %s
+// RUN: %klee --exit-on-error --use-asm-addresses %t.bc
+// RUN: %llvmgcc -DOVERLAP -g -c -o %t.bc %s
+// RUN: not %klee --exit-on-error --use-asm-addresses %t.bc
+
+#include <assert.h>
+
+
+volatile unsigned char x0 __asm ("0x0021");
+volatile unsigned char whee __asm ("0x0WHEE");
+
+#ifdef OVERLAP
+volatile unsigned int y0 __asm ("0x0030");
+volatile unsigned int y1 __asm ("0x0032");
+#endif
+
+int main() {
+  assert(&x0 == (void*) 0x0021);
+  assert(&whee != (void*) 0x0);
+
+  return 0;
+}
diff --git a/test/Feature/ByteSwap.c b/test/Feature/ByteSwap.c
new file mode 100644
index 00000000..f85ac3b1
--- /dev/null
+++ b/test/Feature/ByteSwap.c
@@ -0,0 +1,16 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --libc=klee --exit-on-error %t1.bc
+
+#include <arpa/inet.h>
+#include <assert.h>
+
+int main() {
+  
+  uint32_t n = 0;
+  klee_make_symbolic(&n, sizeof(n));
+  
+  uint32_t h = ntohl(n);
+  assert(htonl(h) == n);
+  
+  return 0;
+}
diff --git a/test/Feature/CallToUndefinedExternal.cpp b/test/Feature/CallToUndefinedExternal.cpp
new file mode 100644
index 00000000..2f11f29d
--- /dev/null
+++ b/test/Feature/CallToUndefinedExternal.cpp
@@ -0,0 +1,11 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.external.err
+
+extern "C" void poof(void);
+
+int main() {
+  poof();
+
+  return 0;
+}
diff --git a/test/Feature/CheckForImpliedValue.c.failing b/test/Feature/CheckForImpliedValue.c.failing
new file mode 100644
index 00000000..7a088354
--- /dev/null
+++ b/test/Feature/CheckForImpliedValue.c.failing
@@ -0,0 +1,23 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: rm -f %t1.log
+// RUN: %klee --log-file %t1.log --debug-check-for-implied-values %t1.bc
+// RUN: grep "= 0 (ok)" %t1.log
+// RUN: grep "= 2 (missed)" %t1.log
+
+#define swap(x) (((x)>>16) | (((x)&0xFFFF)<<16))
+int main() {
+  unsigned x, y;
+  
+  klee_make_symbolic(&x, sizeof x);
+  klee_make_symbolic(&y, sizeof y);
+
+  if (!x) { // should give x = 0 hit by ivc
+    printf("ok\n");
+  } else {
+    if (swap(y) == 0x00020000) { // should give y = 2 missed by ivc
+      printf("ok\n");
+    }
+  }
+
+  return 0;
+}
diff --git a/test/Feature/CheckMemoryAccess.c b/test/Feature/CheckMemoryAccess.c
new file mode 100644
index 00000000..dd6e8745
--- /dev/null
+++ b/test/Feature/CheckMemoryAccess.c
@@ -0,0 +1,26 @@
+// RUN: %llvmgcc -g -c %s -o %t.bc
+// RUN: %klee %t.bc > %t.log
+// RUN: grep -q "good" %t.log
+// RUN: not grep -q "bad" %t.log
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int main() {
+  char buf[4];
+
+  klee_check_memory_access(&buf, 1);
+  printf("good\n");
+  if (klee_range(0, 2, "range1")) {
+    klee_check_memory_access(0, 1);
+    printf("null pointer deref: bad\n");
+  }
+
+  if (klee_range(0, 2, "range2")) {
+    klee_check_memory_access(buf, 5);
+    printf("oversize access: bad\n");
+  }
+
+  return 0;
+}
diff --git a/test/Feature/CopyOnWrite.c b/test/Feature/CopyOnWrite.c
new file mode 100644
index 00000000..ee3ea15e
--- /dev/null
+++ b/test/Feature/CopyOnWrite.c
@@ -0,0 +1,26 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --use-random-search --exit-on-error %t1.bc
+
+#include <assert.h>
+
+#define N 5
+
+unsigned branches = 0;
+
+void explode(int *ap, int i, int *result) {
+  if (i<N) {
+    (*result)++;
+    if (ap[i]) // just cause a fork
+      branches++; 
+    return explode(ap, i+1, result);
+  }
+}
+
+int main() {
+  int result = 0;
+  int a[N];
+  klee_make_symbolic(a, sizeof a);
+  explode(a,0,&result);
+  assert(result==N);
+  return 0;
+}
diff --git a/test/Feature/DanglingConcreteReadExpr.c b/test/Feature/DanglingConcreteReadExpr.c
new file mode 100644
index 00000000..1bf44c3f
--- /dev/null
+++ b/test/Feature/DanglingConcreteReadExpr.c
@@ -0,0 +1,22 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: grep "total queries = 2" klee-last/info
+
+#include <assert.h>
+
+int main() {
+  unsigned char x, y;
+
+  klee_make_symbolic(&x, sizeof x);
+  
+  y = x;
+
+  // should be exactly two queries (prove x is/is not 10)
+  // eventually should be 0 when we have fast solver
+  if (x==10) {
+    assert(y==10);
+  }
+
+  klee_silent_exit(0);
+  return 0;
+}
diff --git a/test/Feature/DefineFixedObject.c b/test/Feature/DefineFixedObject.c
new file mode 100644
index 00000000..36822434
--- /dev/null
+++ b/test/Feature/DefineFixedObject.c
@@ -0,0 +1,17 @@
+// RUN: %llvmgcc -c -o %t1.bc %s
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <stdio.h>
+
+#define ADDRESS ((int*) 0x0080)
+
+int main() {
+  klee_define_fixed_object(ADDRESS, 4);
+  
+  int *p = ADDRESS;
+
+  *p = 10;
+  printf("*p: %d\n", *p);
+
+  return 0;
+}
diff --git a/test/Feature/DoubleFree.c b/test/Feature/DoubleFree.c
new file mode 100644
index 00000000..3727ef2b
--- /dev/null
+++ b/test/Feature/DoubleFree.c
@@ -0,0 +1,10 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.ptr.err
+
+int main() {
+  int *x = malloc(4);
+  free(x);
+  free(x);
+  return 0;
+}
diff --git a/test/Feature/DumpStatesOnHalt.c b/test/Feature/DumpStatesOnHalt.c
new file mode 100644
index 00000000..7e9cf46a
--- /dev/null
+++ b/test/Feature/DumpStatesOnHalt.c
@@ -0,0 +1,8 @@
+// RUN: %llvmgcc %s -g -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --stop-after-n-instructions=1 --dump-states-on-halt=true %t1.bc
+// RUN: test -f klee-last/test000001.bout
+
+int main() {
+  int x = 10;
+  return x;
+}
diff --git a/test/Feature/Envp.c b/test/Feature/Envp.c
new file mode 100644
index 00000000..f1f62a72
--- /dev/null
+++ b/test/Feature/Envp.c
@@ -0,0 +1,18 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <assert.h>
+
+int main(int argc, char **argv, char **envp) {
+  unsigned i;
+  assert(argv[argc] == 0);
+  printf("argc: %d, argv: %p, envp: %p\n", argc, argv, envp);
+  printf("--environ--\n");
+  int haspwd = 0;
+  for (i=0; envp[i]; i++) {
+    printf("%d: %s\n", i, envp[i]);
+    haspwd |= strncmp(envp[i], "PWD=", 4)==0;
+  }
+  assert(haspwd);
+  return 0;
+}
diff --git a/test/Feature/ExprLogging.c b/test/Feature/ExprLogging.c
new file mode 100644
index 00000000..2abf0070
--- /dev/null
+++ b/test/Feature/ExprLogging.c
@@ -0,0 +1,43 @@
+// RUN: %llvmgcc %s -emit-llvm -g -O0 -c -o %t1.bc
+// RUN: %klee --use-query-pc-log --write-pcs --write-cvcs %t1.bc 2> %t2.log
+// RUN: %kleaver -print-ast klee-last/test000001.pc
+
+// FIXME: Ideally we would verify a roundtrip that we parsed the pc
+// file and can dump it back out as the same file.
+
+#include <assert.h>
+
+int constantArr[16 ] = {
+  1 <<  0, 1 <<  1, 1 <<  2, 1 <<  3,
+  1 <<  4, 1 <<  5, 1 <<  6, 1 <<  7,
+  1 <<  8, 1 <<  9, 1 << 10, 1 << 11,
+  1 << 12, 1 << 13, 1 << 14, 1 << 15
+};
+
+
+int main() {
+  char buf[4];
+  klee_make_symbolic(buf, sizeof buf);
+
+  buf[1] = 'a';
+
+  constantArr[klee_range(0, 16, "idx.0")] = buf[0];
+
+  // Use this to trigger an interior update list usage.
+  int y = constantArr[klee_range(0, 16, "idx.1")];  
+
+  constantArr[klee_range(0, 16, "idx.2")] = buf[3];
+  
+  buf[klee_range(0, 4, "idx.3")] = 0;
+  klee_assume(buf[0] == 'h');
+  
+  int x = *((int*) buf);
+  klee_assume(x > 2);
+  klee_assume(x == constantArr[12]);
+
+  klee_assume(y != (1 << 5));
+
+  assert(0);
+
+  return 0;
+}
diff --git a/test/Feature/ExternalWeakLinkage.c b/test/Feature/ExternalWeakLinkage.c
new file mode 100644
index 00000000..c2008136
--- /dev/null
+++ b/test/Feature/ExternalWeakLinkage.c
@@ -0,0 +1,11 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <assert.h>
+
+void __attribute__((weak)) IAmSoWeak(int);
+
+int main() {
+  assert(IAmSoWeak==0);
+  return 0;
+}
diff --git a/test/Feature/FunctionPointer.c b/test/Feature/FunctionPointer.c
new file mode 100644
index 00000000..e1ae1e37
--- /dev/null
+++ b/test/Feature/FunctionPointer.c
@@ -0,0 +1,36 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --no-output --exit-on-error %t1.bc
+
+#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");
+  fp("called via fp");
+
+  printf("calling via pass through\n");
+  bar(foo);
+        
+  fp = baz;
+  fp("called via fp");
+
+  xx("called via xx");
+
+#if 0
+  klee_make_symbolic(&fp, sizeof fp);
+  if(fp == baz) {
+    printf("fp = %p, baz = %p\n", fp, baz);
+    fp("calling via symbolic!");
+  }
+#endif
+
+  return 0;
+}
diff --git a/test/Feature/GetValue.c b/test/Feature/GetValue.c
new file mode 100644
index 00000000..391b68e3
--- /dev/null
+++ b/test/Feature/GetValue.c
@@ -0,0 +1,17 @@
+// RUN: %llvmgcc -c -o %t1.bc %s
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <stdio.h>
+#include <assert.h>
+
+int main() {
+  int x = klee_int("x");
+  klee_assume(x > 10);
+  klee_assume(x < 20);
+
+  assert(!klee_is_symbolic(klee_get_value(x)));
+  assert(klee_get_value(x) > 10);
+  assert(klee_get_value(x) < 20);
+
+  return 0;
+}
diff --git a/test/Feature/ImpliedValue.c.failing b/test/Feature/ImpliedValue.c.failing
new file mode 100644
index 00000000..2f169970
--- /dev/null
+++ b/test/Feature/ImpliedValue.c.failing
@@ -0,0 +1,147 @@
+// RUN: rm -f %t4.out %t4.err %t4.log
+// RUN: %llvmgcc %s -emit-llvm -O2 -c -o %t1.bc
+// RUN: llvm-as -f ../_utils._ll -o %t2.bc
+// RUN: llvm-ld -disable-opt -link-as-library %t1.bc %t2.bc -o %t3.bc
+// RUN: %klee --log-file %t4.log --debug-check-for-implied-values %t3.bc > %t4.out 2> %t4.err
+// RUN: ls klee-last | not grep .err
+// RUN: not grep "(missed)" %t4.log
+
+#include <assert.h>
+
+#include "utils.h"
+
+int main() {
+  unsigned char which;
+  volatile unsigned char a,b,c,d,e,f,g,h;
+
+  klee_make_symbolic(&which, sizeof which);
+  klee_make_symbolic(&a, sizeof a);
+  klee_make_symbolic(&b, sizeof b);
+  klee_make_symbolic(&c, sizeof c);
+  klee_make_symbolic(&d, sizeof d);
+  klee_make_symbolic(&e, sizeof e);
+  klee_make_symbolic(&f, sizeof f);
+  klee_make_symbolic(&g, sizeof g);
+  klee_make_symbolic(&h, sizeof h);
+
+  switch (which) {
+// RUN: grep "simple read(2) = value case" %t4.out
+  case 0:
+    if (a == 2) {
+      assert(!klee_is_symbolic(a));
+      printf("simple read(%d) = value case\n", a);
+    }
+    break;
+
+// RUN: grep "select(0) has distinct constant result case (false)" %t4.out
+  case 1:
+    if (util_make_select(a, 12, 14) == 14) {
+      assert(!klee_is_symbolic(a));
+      printf("select(%d) has distinct constant result case (false)\n", a);
+    }
+    break;
+
+// RUN: grep "select(0) has distinct constant result case (true)" %t4.out
+  case 2:
+    if (util_make_select(!a, 12, 14) == 12) {
+      assert(!klee_is_symbolic(a));
+      printf("select(%d) has distinct constant result case (true)\n", a);
+    }
+    break;
+
+// RUN: grep "concat2(0xBE,0xEF) = value case" %t4.out
+  case 3:
+    if (util_make_concat2(a,b) == 0xBEEF) {
+      assert(!klee_is_symbolic(a));
+      assert(!klee_is_symbolic(b));
+      printf("concat2(0x%X,0x%X) = value case\n",
+             a, b);
+    }
+    break;
+
+// RUN: grep "concat4(0xDE,0xAD,0xBE,0xEF) = value case" %t4.out
+  case 4:
+    if (util_make_concat4(a,b,c,d) == 0xDEADBEEF) {
+      assert(!klee_is_symbolic(a));
+      assert(!klee_is_symbolic(b));
+      assert(!klee_is_symbolic(c));
+      assert(!klee_is_symbolic(d));
+      printf("concat4(0x%X,0x%X,0x%X,0x%X) = value case\n",
+             a, b, c, d);
+    }
+    break;
+
+// RUN: grep "concat8(0xDE,0xAD,0xBE,0xEF,0xAB,0xCD,0xAB,0xCD) = value case" %t4.out
+  case 5:
+    if (util_make_concat8(a,b,c,d,e,f,g,h) == 0xDEADBEEFABCDABCDLL) {
+      assert(!klee_is_symbolic(a));
+      assert(!klee_is_symbolic(b));
+      assert(!klee_is_symbolic(c));
+      assert(!klee_is_symbolic(d));
+      assert(!klee_is_symbolic(e));
+      assert(!klee_is_symbolic(f));
+      assert(!klee_is_symbolic(g));
+      assert(!klee_is_symbolic(h));
+      printf("concat8(0x%X,0x%X,0x%X,0x%X,0x%X,0x%X,0x%X,0x%X) = value case\n",
+             a, b, c, d, e, f, g, h);
+    }
+    break;
+
+// RUN: grep "and(0,0) = true case" %t4.out
+  case 6:
+    if (util_make_and_i1(!a, !b)) {
+      assert(!klee_is_symbolic(a));
+      assert(!klee_is_symbolic(b));      
+      printf("and(%d,%d) = true case\n", a, b);
+    }
+    break;
+
+// RUN: grep "or(0,0) = false case" %t4.out
+  case 7:
+    if (!util_make_or_i1(a, b)) {
+      assert(!klee_is_symbolic(a));
+      assert(!klee_is_symbolic(b));      
+      printf("or(%d,%d) = false case\n", a, b);
+    }
+    break;
+
+    // we use concat to prevent folding, will need to fix if that gets
+    // partial evaluated
+// RUN: grep "add constant case: 0xDE" %t4.out
+  case 8:
+    if (util_make_concat2(a+0xCD,0xCD) == 0xABCD) { 
+      assert(!klee_is_symbolic(a));
+      printf("add constant case: 0x%X\n", a);
+    }
+    break;
+
+// RUN: grep "sub constant case: 0x60" %t4.out
+  case 9:
+    if (util_make_concat2(0x0B-a,0xCD) == 0xABCD) { 
+      assert(!klee_is_symbolic(a));
+      printf("sub constant case: 0x%X\n", a);
+    }
+    break;
+
+// RUN: grep "xor constant case: 0xA0" %t4.out
+  case 10:
+    if (util_make_concat2(0x0B ^ a,0xCD) == 0xABCD) { 
+      assert(!klee_is_symbolic(a));
+      printf("xor constant case: 0x%X\n", a);
+    }
+    break;
+
+// RUN: grep "sext constant case: 244" %t4.out
+  case 11:
+    if (! util_make_or_i1(((short) (signed char) a) + 12,b)) {
+      assert(!klee_is_symbolic(a));
+      printf("sext constant case: %d\n", a);
+    }
+    break;
+
+  default:
+    break;
+  }
+
+  return 0;
+}
diff --git a/test/Feature/InAndOutOfBounds.c b/test/Feature/InAndOutOfBounds.c
new file mode 100644
index 00000000..18e5d2b2
--- /dev/null
+++ b/test/Feature/InAndOutOfBounds.c
@@ -0,0 +1,19 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.ptr.err -o -f klee-last/test000002.ptr.err 
+// RUN: test ! -f klee-last/test000001.ptr.err -o ! -f klee-last/test000002.ptr.err 
+// RUN: test ! -f klee-last/test000003.bout
+
+unsigned klee_urange(unsigned start, unsigned end) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  if (x-start>=end-start) klee_silent_exit(0);
+  return x;
+}
+
+int main() {
+  int *x = malloc(4);
+  x[klee_urange(0,2)] = 1;
+  free(x);
+  return 0;
+}
diff --git a/test/Feature/IndirectCallToBuiltin.c b/test/Feature/IndirectCallToBuiltin.c
new file mode 100644
index 00000000..591a5601
--- /dev/null
+++ b/test/Feature/IndirectCallToBuiltin.c
@@ -0,0 +1,15 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <stdlib.h>
+#include <stdio.h>
+
+int main() {
+  void *(*allocator)(size_t) = malloc;
+  int *mem = allocator(10);
+
+  printf("mem: %p\n", mem);
+  printf("mem[0]: %d\n", mem[0]);
+
+  return 0;
+}
diff --git a/test/Feature/IndirectCallToExternal.c b/test/Feature/IndirectCallToExternal.c
new file mode 100644
index 00000000..4603213b
--- /dev/null
+++ b/test/Feature/IndirectCallToExternal.c
@@ -0,0 +1,15 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+
+int main() {
+  int (*scmp)(char*,char*) = strcmp;
+
+  assert(scmp("hello","hi") < 0);
+
+  return 0;
+}
diff --git a/test/Feature/InvalidBitfieldAccess.c.failing b/test/Feature/InvalidBitfieldAccess.c.failing
new file mode 100644
index 00000000..ae8bfe5e
--- /dev/null
+++ b/test/Feature/InvalidBitfieldAccess.c.failing
@@ -0,0 +1,28 @@
+// RUN: %llvmgcc -c -o %t1.bc %s
+// RUN: %klee --exit-on-error %t1.bc
+
+// This is a bug in llvm-gcc4.0 but seems to be fixed in llvm-gcc4.2,
+// its included here mostly as a reminder. 
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+struct foo {
+  unsigned int a : 5;
+  unsigned int b : 10;
+  unsigned int c : 1;
+} __attribute__((packed));
+
+int main() {
+  struct foo *a = malloc(sizeof *a);
+
+  a->b = 12; // problem here is that llvm-gcc emits a 4 byte access
+             // which is out of bounds.
+
+  int x = a->b;
+
+  assert(x == 12);
+
+  return 0;
+}
diff --git a/test/Feature/IsSymbolic.c b/test/Feature/IsSymbolic.c
new file mode 100644
index 00000000..4a86368a
--- /dev/null
+++ b/test/Feature/IsSymbolic.c
@@ -0,0 +1,16 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+
+#include <assert.h>
+
+int main() {
+  int x, y, z = 0;
+  klee_make_symbolic(&x, sizeof x);
+  klee_make_symbolic(&y, sizeof y);
+  if (x) {
+    assert(klee_is_symbolic(y));
+  } else {
+    assert(!klee_is_symbolic(z));
+  }
+  return 0;
+}
diff --git a/test/Feature/KleeReportError.c b/test/Feature/KleeReportError.c
new file mode 100644
index 00000000..dda72fd0
--- /dev/null
+++ b/test/Feature/KleeReportError.c
@@ -0,0 +1,23 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --emit-all-errors %t2.bc > %t3.log
+// RUN: ls klee-last/ | grep .my.err | wc -l | grep 2
+#include <stdio.h>
+#include <assert.h>
+
+int main(int argc, char** argv) {
+  int x, y, *p = 0;
+  
+  klee_make_symbolic(&x, sizeof x);
+  klee_make_symbolic(&y, sizeof y);
+
+  if (x)
+    fprintf(stderr, "x\n");
+  else fprintf(stderr, "!x\n");
+
+  if (y) {
+    fprintf(stderr, "My error\n");
+    klee_report_error(__FILE__, __LINE__, "My error", "my.err");
+  }
+
+  return 0;
+}
diff --git a/test/Feature/LongDoubleSupport.c b/test/Feature/LongDoubleSupport.c
new file mode 100644
index 00000000..b4631832
--- /dev/null
+++ b/test/Feature/LongDoubleSupport.c
@@ -0,0 +1,20 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc > %t2.out
+
+#include <stdio.h>
+#include <float.h>
+
+// FIXME: This doesn't really work at all, it just doesn't
+// crash. Until we have wide constant support, that is all we care
+// about; the only reason this comes up is in initialization of
+// constants, we don't actually end up seeing much code which uses long
+// double.
+int main() {
+  long double a = LDBL_MAX;
+  long double b = -1;
+  long double c = a + b;
+  printf("a = %Lg\n", a);
+  printf("b = %Lg\n", b);
+  printf("c = %Lg\n", c);
+  return 0;
+}
diff --git a/test/Feature/LowerSwitch.c b/test/Feature/LowerSwitch.c
new file mode 100644
index 00000000..c4d9644a
--- /dev/null
+++ b/test/Feature/LowerSwitch.c
@@ -0,0 +1,30 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t.bc
+// RUN: %klee --exit-on-error --allow-external-sym-calls --switch-type=internal %t.bc
+// RUN: not test -f klee-last/test000010.bout
+// RUN: %klee --exit-on-error --allow-external-sym-calls --switch-type=simple %t.bc
+// RUN: test -f klee-last/test000010.bout
+
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+  int c = klee_range(0, 256, "range");
+  
+  switch(c) {
+  case 0: printf("0\n"); break;
+  case 10: printf("10\n"); break;
+  case 16: printf("16\n"); break;
+  case 17: printf("17\n"); break;
+  case 18: printf("18\n"); break;
+  case 19: printf("19\n"); break;
+#define C(x) case x: case x+1: case x+2: case x+3
+#define C2(x) C(x): C(x+4): C(x+8): C(x+12)
+#define C3(x) C2(x): C2(x+16): C2(x+32): C2(x+48)
+  C3(128):
+    printf("bignums: %d\n", c); break;
+  default: 
+    printf("default\n");
+    break;
+  }
+
+  return 0;
+}
diff --git a/test/Feature/MakeConcreteSymbolic.c b/test/Feature/MakeConcreteSymbolic.c
new file mode 100644
index 00000000..29b43a04
--- /dev/null
+++ b/test/Feature/MakeConcreteSymbolic.c
@@ -0,0 +1,19 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+// RUN: grep "done: total queries = 0" klee-last/info
+// RUN: %klee --make-concrete-symbolic=1 --exit-on-error %t1.bc
+// RUN: grep "done: total queries = 2" klee-last/info
+
+
+#include <assert.h>
+
+#define N 2
+int main() {
+  int i;
+  char a;
+  
+  a = 10;
+  assert(a == 10);
+
+  return 0;
+}
diff --git a/test/Feature/MakeSymbolicName.c b/test/Feature/MakeSymbolicName.c
new file mode 100644
index 00000000..c1f11424
--- /dev/null
+++ b/test/Feature/MakeSymbolicName.c
@@ -0,0 +1,17 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t1.bc
+// RUN: %klee --use-random-search --exit-on-error %t1.bc
+
+#include <assert.h>
+
+int main() {
+  int a[4] = {1, 2, 3, 4};
+  unsigned i;
+
+  klee_make_symbolic_name(&i, sizeof(i), "index");  
+  if (i > 3)
+    klee_silent_exit(0);
+
+  assert(a[i] << 1 != 5);
+  if (a[i] << 1 == 6)
+    assert(i == 2);
+}
diff --git a/test/Feature/MemoryLimit.c b/test/Feature/MemoryLimit.c
new file mode 100644
index 00000000..3b1bacaf
--- /dev/null
+++ b/test/Feature/MemoryLimit.c
@@ -0,0 +1,37 @@
+// RUN: %llvmgcc -DLITTLE_ALLOC -g -c %s -o %t.little.bc
+// RUN: %llvmgcc -g -c %s -o %t.big.bc
+// RUN: %klee --max-memory=20 %t.little.bc > %t.little.log
+// RUN: %klee --max-memory=20 %t.big.bc > %t.big.log
+// RUN: not grep -q "DONE" %t.little.log
+// RUN: not grep -q "DONE" %t.big.log
+
+#include <stdlib.h>
+
+int main() {
+  int i, j, x=0;
+  
+#ifdef LITTLE_ALLOC
+  printf("IN LITTLE ALLOC\n");
+    
+  // 200 MBs total (in 32 byte chunks)
+  for (i=0; i<100; i++) {
+    for (j=0; j<(1<<16); j++)
+      malloc(1<<5);
+  }
+#else
+  printf("IN BIG ALLOC\n");
+  
+  // 200 MBs total
+  for (i=0; i<100; i++) {
+    malloc(1<<21);
+    
+    // Ensure we hit the periodic check
+    for (j=0; j<10000; j++)
+      x++;
+  }
+#endif
+
+  printf("DONE!\n");
+
+  return x;
+}
diff --git a/test/Feature/MultipleFreeResolution.c b/test/Feature/MultipleFreeResolution.c
new file mode 100644
index 00000000..872d6856
--- /dev/null
+++ b/test/Feature/MultipleFreeResolution.c
@@ -0,0 +1,39 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --emit-all-errors %t1.bc
+// RUN: ls klee-last/ | grep .out | wc -l | grep 4
+// RUN: ls klee-last/ | grep .err | wc -l | grep 3
+
+#include <stdlib.h>
+#include <stdio.h>
+
+unsigned klee_urange(unsigned start, unsigned end) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  if (x-start>=end-start) klee_silent_exit(0);
+  return x;
+}
+
+int *make_int(int i) {
+  int *x = malloc(sizeof(*x));
+  *x = i;
+  return x;
+}
+
+int main() {
+  int *buf[4];
+  int i,s;
+
+  for (i=0; i<3; i++)
+    buf[i] = make_int(i);
+  buf[3] = 0;
+
+  s = klee_urange(0,4);
+
+  free(buf[s]);
+
+  for (i=0; i<3; i++) {
+    printf("*buf[%d] = %d\n", i, *buf[i]);
+  }
+
+  return 0;
+}
diff --git a/test/Feature/MultipleReadResolution.c b/test/Feature/MultipleReadResolution.c
new file mode 100644
index 00000000..9297cf8d
--- /dev/null
+++ b/test/Feature/MultipleReadResolution.c
@@ -0,0 +1,43 @@
+// RUN: echo "x" > %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc > %t1.log
+// RUN: diff %t1.res %t1.log
+
+#include <stdio.h>
+
+unsigned klee_urange(unsigned start, unsigned end) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  if (x-start>=end-start) klee_silent_exit(0);
+  return x;
+}
+
+int *make_int(int i) {
+  int *x = malloc(sizeof(*x));
+  *x = i;
+  return x;
+}
+
+int main() {
+  int *buf[4];
+  int i,s,t;
+
+  for (i=0; i<4; i++)
+    buf[i] = make_int((i+1)*2);
+
+  s = klee_urange(0,4);
+
+  int x = *buf[s];
+
+  if (x == 4)
+    if (s!=1)
+      abort();
+
+  printf("x\n");
+  fflush(stdout);
+
+  return 0;
+}
diff --git a/test/Feature/MultipleReallocResolution.c b/test/Feature/MultipleReallocResolution.c
new file mode 100644
index 00000000..b1a14ace
--- /dev/null
+++ b/test/Feature/MultipleReallocResolution.c
@@ -0,0 +1,63 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: ls klee-last/ | grep .err | wc -l | grep 2
+// RUN: ls klee-last/ | grep .ptr.err | wc -l | grep 2
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+unsigned klee_urange(unsigned start, unsigned end) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  if (x-start>=end-start) klee_silent_exit(0);
+  return x;
+}
+
+int *make_int(int i, int N) {
+  int *x = malloc(sizeof(*x) * N);
+  *x = i;
+  return x;
+}
+
+int main() {
+  int *buf[4];
+
+  buf[0] = malloc(sizeof(int)*4);
+  buf[1] = malloc(sizeof(int));
+  buf[2] = 0; // gets malloc'd
+  buf[3] = (int*) 0xdeadbeef; // boom
+
+  buf[0][0] = 10;
+  buf[0][1] = 42;
+  buf[1][0] = 20;
+
+  int i = klee_urange(0,4);
+  int new_size = 2 * sizeof(int) * klee_urange(0,2); // 0 or 8
+
+  // whee, party time, needs to:
+  // Fork if size == 0, in which case all buffers get free'd and
+  // we will crash in prints below.
+  // Fork if buf[s] == 0, in which case the buffer gets malloc'd (for s==2)
+  // Fork on other buffers (s in [0,1]) and do realloc
+  //   for s==0 this is shrinking
+  //   for s==1 this is growing
+  buf[i] = realloc(buf[i], new_size);
+
+  if (new_size == 0) {
+    assert(!buf[2]); // free(0) is a no-op
+    if (i==0) assert(!buf[0] && buf[1]);
+    if (i==1) assert(buf[0] && !buf[1]);
+    assert(i != 3); // we should have crashed on free of invalid
+  } else {
+    assert(new_size == sizeof(int)*2);
+    assert(buf[0][0] == 10);
+    assert(buf[0][1] == 42); // make sure copied
+    assert(buf[1][0] == 20);
+    if (i==1) { int x = buf[1][1]; } // should be safe
+    if (i==2) { int x = buf[2][0]; } // should be safe
+    assert(i != 3); // we should have crashed on realloc of invalid
+  }
+
+  return 0;
+}
diff --git a/test/Feature/MultipleWriteResolution.c b/test/Feature/MultipleWriteResolution.c
new file mode 100644
index 00000000..f07b9710
--- /dev/null
+++ b/test/Feature/MultipleWriteResolution.c
@@ -0,0 +1,43 @@
+// RUN: echo "x" > %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: echo "x" >> %t1.res
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc > %t1.log
+// RUN: diff %t1.res %t1.log
+
+#include <stdio.h>
+
+unsigned klee_urange(unsigned start, unsigned end) {
+  unsigned x;
+  klee_make_symbolic(&x, sizeof x);
+  if (x-start>=end-start) klee_silent_exit(0);
+  return x;
+}
+
+int *make_int(int i) {
+  int *x = malloc(sizeof(*x));
+  *x = i;
+  return x;
+}
+
+int main() {
+  int *buf[4];
+  int i,s,t;
+
+  for (i=0; i<4; i++)
+    buf[i] = make_int((i+1)*2);
+
+  s = klee_urange(0,4);
+
+  *buf[s] = 5;
+
+  if ((*buf[0] + *buf[1] + *buf[2] + *buf[3]) == 17)
+    if (s!=3)
+      abort();
+
+  printf("x\n");
+  fflush(stdout);
+
+  return 0;
+}
diff --git a/test/Feature/NamedSeedMatching.c b/test/Feature/NamedSeedMatching.c
new file mode 100644
index 00000000..6d52e7a4
--- /dev/null
+++ b/test/Feature/NamedSeedMatching.c
@@ -0,0 +1,41 @@
+// RUN: %llvmgcc -c -g %s -o %t.bc
+// RUN: rm -rf %t.out
+// RUN: %klee --output-dir=%t.out %t.bc "initial"
+// RUN: test -f %t.out/test000001.bout
+// RUN: not test -f %t.out/test000002.bout
+// RUN: %klee --only-replay-seeds --named-seed-matching --seed-out %t.out/test000001.bout %t.bc > %t.log
+// RUN: grep -q "a==3" %t.log
+// RUN: grep -q "b==4" %t.log
+// RUN: grep -q "c==5" %t.log
+// RUN: grep -q "x==6" %t.log
+
+#include <string.h>
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+  int a, b, c, x;
+
+  if (argc==2 && strcmp(argv[1], "initial") == 0) {
+    klee_make_symbolic_name(&a, sizeof a, "a");
+    klee_make_symbolic_name(&b, sizeof b, "b");
+    klee_make_symbolic_name(&c, sizeof c, "c");
+    klee_make_symbolic_name(&x, sizeof x, "a");
+
+    klee_assume(a == 3);
+    klee_assume(b == 4);
+    klee_assume(c == 5);
+    klee_assume(x == 6);
+  } else {
+    klee_make_symbolic_name(&a, sizeof a, "a");
+    klee_make_symbolic_name(&c, sizeof c, "c");
+    klee_make_symbolic_name(&b, sizeof b, "b");
+    klee_make_symbolic_name(&x, sizeof x, "a");
+  }
+
+  if (a==3) printf("a==3\n");
+  if (b==4) printf("b==4\n");
+  if (c==5) printf("c==5\n");
+  if (x==6) printf("x==6\n");
+
+  return 0;
+}
diff --git a/test/Feature/OneFreeError.c b/test/Feature/OneFreeError.c
new file mode 100644
index 00000000..8eb13298
--- /dev/null
+++ b/test/Feature/OneFreeError.c
@@ -0,0 +1,10 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.ptr.err
+
+int main() {
+  int *x = malloc(4);
+  free(x);
+  x[0] = 1;
+  return 0;
+}
diff --git a/test/Feature/OneOutOfBounds.c b/test/Feature/OneOutOfBounds.c
new file mode 100644
index 00000000..11a9eecb
--- /dev/null
+++ b/test/Feature/OneOutOfBounds.c
@@ -0,0 +1,10 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: test -f klee-last/test000001.ptr.err
+
+int main() {
+  int *x = malloc(4);
+  x[1] = 1;
+  free(x);
+  return 0;
+}
diff --git a/test/Feature/Optimize.c b/test/Feature/Optimize.c
new file mode 100644
index 00000000..3c9159c7
--- /dev/null
+++ b/test/Feature/Optimize.c
@@ -0,0 +1,22 @@
+// RUN: %llvmgcc %s --emit-llvm -O0 -c -o %t2.bc
+// RUN: rm -f %t2.log
+// RUN: %klee --stop-after-n-instructions=100 --optimize %t2.bc > %t3.log
+// RUN: echo "good" > %t3.good
+// RUN: diff %t3.log %t3.good
+
+// should complete by 100 instructions if opt is on
+
+int main() {
+  int i, res = 0;
+
+  for (i=1; i<=1000; i++)
+    res += i;
+
+  if (res == (1000*1001)/2) {
+    printf("good\n");
+  } else {
+    printf("bad\n");
+  }
+  
+  return 0;
+}
diff --git a/test/Feature/OverlappedError.c b/test/Feature/OverlappedError.c
new file mode 100644
index 00000000..3c79380c
--- /dev/null
+++ b/test/Feature/OverlappedError.c
@@ -0,0 +1,19 @@
+// RUN: %llvmgcc %s -g -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc
+// RUN: ls klee-last/ | grep .out | wc -l | grep 4
+// RUN: ls klee-last/ | grep .ptr.err | wc -l | grep 2
+
+#include <stdlib.h>
+
+int main() {
+  if (klee_range(0,2, "range")) {
+    char *x = malloc(8);
+    *((int*) &x[klee_range(0,6, "range")]) = 1;
+    free(x);
+  } else {
+    char *x = malloc(8);
+    *((int*) &x[klee_range(-1,5, "range")]) = 1;
+        free(x);
+  }
+  return 0;
+}
diff --git a/test/Feature/PreferCex.c b/test/Feature/PreferCex.c
new file mode 100644
index 00000000..d73b6076
--- /dev/null
+++ b/test/Feature/PreferCex.c
@@ -0,0 +1,18 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+// RUN: klee-bout-tool klee-last/test000001.bout | grep -F 'Hi\x00\x00'
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int main() {
+  char buf[4];
+
+  klee_make_symbolic(buf, sizeof buf);
+  klee_prefer_cex(buf, buf[0]=='H');
+  klee_prefer_cex(buf, buf[1]=='i');
+  klee_prefer_cex(buf, buf[2]=='\0');
+
+  return 0;
+}
diff --git a/test/Feature/RaiseAsm.c b/test/Feature/RaiseAsm.c
new file mode 100644
index 00000000..5b8acab4
--- /dev/null
+++ b/test/Feature/RaiseAsm.c
@@ -0,0 +1,39 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <assert.h>
+
+typedef unsigned short uint16;
+typedef unsigned int   uint32;
+
+uint16 byteswap_uint16(uint16 x) {
+  return (x << 8) | (x >> 8);
+}
+uint32 byteswap_uint32(uint32 x) {
+  return ((byteswap_uint16(x) << 16) |
+          (byteswap_uint16(x >> 16)));
+}
+
+uint16 byteswap_uint16_asm(uint16 x) {
+  uint16 res;
+  __asm__("rorw $8, %w0" : "=r" (res) : "0" (x) : "cc");
+  return res;
+}
+
+uint32 byteswap_uint32_asm(uint32 x) {
+  uint32 res;
+  __asm__("rorw $8, %w0;"
+          "rorl $16, %0;"
+          "rorw $8, %w0" : "=r" (res) : "0" (x) : "cc");
+  return res;
+}
+
+int main() {
+  uint16 ui16 = klee_int("ui16");
+  uint32 ui32 = klee_int("ui32");
+
+  assert(ui16 == byteswap_uint16(byteswap_uint16_asm(ui16)));
+  assert(ui32 == byteswap_uint32(byteswap_uint32_asm(ui32)));
+
+  return 0;
+}
diff --git a/test/Feature/ReallocFailure.c b/test/Feature/ReallocFailure.c
new file mode 100644
index 00000000..e5105c33
--- /dev/null
+++ b/test/Feature/ReallocFailure.c
@@ -0,0 +1,18 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee --exit-on-error %t1.bc
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+int main() {
+  int *p = malloc(sizeof(int)*2);
+  assert(p);
+  p[1] = 52;
+
+  int *p2 = realloc(p, 1<<30);
+  assert(p2 == 0);
+  assert(p[1] == 52);
+
+  return 0;
+}
diff --git a/test/Feature/ReplayPath.c b/test/Feature/ReplayPath.c
new file mode 100644
index 00000000..3f01fa80
--- /dev/null
+++ b/test/Feature/ReplayPath.c
@@ -0,0 +1,27 @@
+// RUN: echo "1" > %t1.path
+// RUN: echo "0" >> %t1.path
+// RUN: echo "1" >> %t1.path
+// RUN: echo "0" >> %t1.path
+// RUN: echo "1" >> %t1.path
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --replay-path %t1.path %t2.bc > %t3.log
+// RUN: echo "res: 110" > %t3.good
+// RUN: diff %t3.log %t3.good
+
+int main() {
+  int res = 1;
+  int x;
+
+  klee_make_symbolic(&x, sizeof x);
+
+  if (x&1) res *= 2;
+  if (x&2) res *= 3;
+  if (x&4) res *= 5;
+
+  // get forced branch coverage
+  if (x&2) res *= 7;
+  if (!(x&2)) res *= 11;
+  printf("res: %d\n", res);
+ 
+  return 0;
+}
diff --git a/test/Feature/Searchers.c b/test/Feature/Searchers.c
new file mode 100644
index 00000000..95ebddf2
--- /dev/null
+++ b/test/Feature/Searchers.c
@@ -0,0 +1,52 @@
+// RUN: %llvmgcc %s --emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee %t2.bc
+// RUN: %klee --use-random-search %t2.bc
+// RUN: %klee --use-non-uniform-random-search %t2.bc
+// RUN: %klee --use-non-uniform-random-search --weight-type=query-cost %t2.bc
+// RUN: %klee --use-batching-search %t2.bc
+// RUN: %klee --use-batching-search --use-random-search %t2.bc
+// RUN: %klee --use-batching-search --use-non-uniform-random-search %t2.bc
+// RUN: %klee --use-batching-search --use-non-uniform-random-search --weight-type=query-cost %t2.bc
+// RUN: %klee --use-merge --debug-log-merge --debug-log-state-merge %t2.bc
+// RUN: %klee --use-merge --use-batching-search %t2.bc
+// RUN: %klee --use-merge --use-batching-search --use-random-search %t2.bc
+// RUN: %klee --use-merge --use-batching-search --use-non-uniform-random-search %t2.bc
+// RUN: %klee --use-merge --use-batching-search --use-non-uniform-random-search --weight-type=query-cost %t2.bc
+// RUN: %klee --use-iterative-deepening-time-search --use-batching-search %t2.bc
+// RUN: %klee --use-iterative-deepening-time-search --use-batching-search --use-random-search %t2.bc
+// RUN: %klee --use-iterative-deepening-time-search --use-batching-search --use-non-uniform-random-search %t2.bc
+// RUN: %klee --use-iterative-deepening-time-search --use-batching-search --use-non-uniform-random-search --weight-type=query-cost %t2.bc
+
+
+/* this test is basically just for coverage and doesn't really do any
+   correctness check (aside from testing that the various combinations
+   don't crash) */
+
+int validate(char *buf, int N) {
+
+  int i;
+
+  for (i=0; i<N; i++) {
+    if (buf[i]==0) {
+      klee_merge();
+      return 0;
+    }
+  }
+  
+  klee_merge();
+  return 1;
+}
+
+#ifndef SYMBOLIC_SIZE
+#define SYMBOLIC_SIZE 15
+#endif
+int main(int argc, char **argv) {
+  int N = SYMBOLIC_SIZE;
+  unsigned char *buf = malloc(N);
+  int i;
+  
+  klee_make_symbolic(buf, N);
+  if (validate(buf, N))
+    return buf[0];
+  return 0;
+}
diff --git a/test/Feature/SetForking.c b/test/Feature/SetForking.c
new file mode 100644
index 00000000..8620110d
--- /dev/null
+++ b/test/Feature/SetForking.c
@@ -0,0 +1,28 @@
+// RUN: %llvmgcc -g -c %s -o %t.bc
+// RUN: %klee %t.bc > %t.log
+// RUN: sort %t.log | uniq -c > %t.uniq.log
+// RUN: grep "1 A" %t.uniq.log
+// RUN: grep "1 B" %t.uniq.log
+// RUN: grep "1 C" %t.uniq.log
+
+#include <stdio.h>
+
+int main() {
+  klee_set_forking(0);
+  
+  if (klee_range(0, 2, "range")) {
+    printf("A\n");
+  } else {
+    printf("A\n");
+  }
+
+  klee_set_forking(1);
+
+  if (klee_range(0, 2, "range")) {
+    printf("B\n");
+  } else {
+    printf("C\n");
+  }
+
+  return 0;
+}
diff --git a/test/Feature/Vararg.c b/test/Feature/Vararg.c
new file mode 100644
index 00000000..f782c15e
--- /dev/null
+++ b/test/Feature/Vararg.c
@@ -0,0 +1,82 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t1.bc
+// RUN: %klee %t1.bc > %t2.out
+// RUN: grep "types: (52, 37, 2.00, (9,12,15))" %t2.out
+// RUN: test -f klee-last/test000001.ptr.err
+
+#include <stdarg.h>
+#include <assert.h>
+#include <stdio.h>
+
+struct triple {
+  int first, second, third;
+};
+
+int test1(int x, ...) {
+  va_list ap;
+  va_start(ap, x);
+  int i32 = va_arg(ap, int);
+  long long i64 = va_arg(ap, long long);
+  double d = va_arg(ap, double);
+  struct triple p = va_arg(ap, struct triple);
+  printf("types: (%d, %lld, %.2f, (%d,%d,%d))\n", i32, i64, d, p.first, p.second, p.third);
+  va_end(ap);
+}
+
+int sum(int N, ...) {
+  int i, res = 0;
+  va_list ap,ap2;
+  
+  va_start(ap, N);
+  for (i=0; i<N; i++) {
+    if (i==1)
+      va_copy(ap2, ap);
+    res += va_arg(ap, int);
+  }
+  for (i=0; i<N-1; i++)
+    res += va_arg(ap2, int);
+  va_end(ap);
+
+  return res;
+}
+
+// test using aps in an array (no multiple resolution
+// testing, though)
+int va_array(int N, ...) {
+  va_list aps[2];
+  unsigned i;
+  unsigned sum1 = 0, sum2 = 0;
+
+  for (i=0; i<2; i++)
+    va_start(aps[i], N);
+  
+  for (i=0; i<N; i++) {
+    unsigned cmd = va_arg(aps[0], int);
+
+    if (cmd==0) {
+      sum1 += va_arg(aps[0],int);
+    } else if (cmd==1) {
+      sum2 += va_arg(aps[1],int);
+    } else if (cmd==2) {
+      va_copy(aps[1], aps[0]);
+    }
+  }
+
+  for (i=0; i<2; i++)
+    va_end(aps[i]);
+
+  return 3*sum1 + 5*sum2;
+}
+
+int main() {
+  struct triple p = { 9, 12, 15 };
+  test1(-1, 52, 37ll, 2.0, p);
+
+  assert(sum(2, 3, 4) == 11);
+  assert(sum(0) == 0);
+  assert(va_array(5, 0, 5, 1, 1, 2, 1)==45); // 15 + 30
+
+  // should give memory error
+  test1(-1, 52, 37, 2.0, p);
+
+  return 0;
+}
diff --git a/test/Feature/WithLibc.c b/test/Feature/WithLibc.c
new file mode 100644
index 00000000..5e84eb4a
--- /dev/null
+++ b/test/Feature/WithLibc.c
@@ -0,0 +1,22 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t2.bc
+// RUN: %klee --libc=klee %t2.bc > %t3.log
+// RUN: echo "good" > %t3.good
+// RUN: diff %t3.log %t3.good
+
+int main() {
+  char buf[4];
+  char *s = "foo";
+
+  klee_make_symbolic(buf, sizeof buf);
+  buf[3] = 0;
+
+  if (strcmp(buf, s)==0) {
+    if (buf[0]=='f' && buf[1]=='o' && buf[2]=='o' && buf[3]==0) {
+      printf("good\n");
+    } else {
+      printf("bad\n");
+    }
+  }
+  
+  return 0;
+}
diff --git a/test/Feature/WriteCov.c b/test/Feature/WriteCov.c
new file mode 100644
index 00000000..defc7e59
--- /dev/null
+++ b/test/Feature/WriteCov.c
@@ -0,0 +1,15 @@
+// RUN: %llvmgcc %s -emit-llvm -g -c -o %t2.bc
+// RUN: %klee --exit-on-error --write-cov %t2.bc
+// RUN: grep WriteCov.c:10 klee-last/test000002.cov
+// RUN: grep WriteCov.c:12 klee-last/test000001.cov
+
+#include <assert.h>
+
+int main() {
+  if (klee_range(0,2, "range")) {
+    assert(__LINE__ == 10); printf("__LINE__ = %d\n", __LINE__);
+  } else {
+    assert(__LINE__ == 12); printf("__LINE__ = %d\n", __LINE__);
+  }
+  return 0;
+}
diff --git a/test/Feature/_utils._ll b/test/Feature/_utils._ll
new file mode 100644
index 00000000..32a73bb1
--- /dev/null
+++ b/test/Feature/_utils._ll
@@ -0,0 +1,71 @@
+define i32 @util_make_and_i1(i32 %a, i32 %b) {
+        %a_i1 = icmp ne i32 %a, 0
+        %b_i1 = icmp ne i32 %b, 0
+        %res_i1 = and i1 %a_i1, %b_i1
+        %res = zext i1 %res_i1 to i32
+        ret i32 %res
+}
+
+define i32 @util_make_or_i1(i32 %a, i32 %b) {
+        %a_i1 = icmp ne i32 %a, 0
+        %b_i1 = icmp ne i32 %b, 0
+        %res_i1 = or i1 %a_i1, %b_i1
+        %res = zext i1 %res_i1 to i32
+        ret i32 %res
+}
+
+define i16 @util_make_concat2(i8 %a, i8 %b) {
+        %tmp = alloca i16
+        %tmp8 = bitcast i16* %tmp to i8*
+        %p0 = getelementptr i8* %tmp8, i32 0
+        %p1 = getelementptr i8* %tmp8, i32 1
+        store i8 %b, i8* %p0
+        store i8 %a, i8* %p1
+        %concat = load i16* %tmp
+        ret i16 %concat
+}
+
+define i32 @util_make_concat4(i8 %a, i8 %b, i8 %c, i8 %d) {
+        %tmp = alloca i32
+        %tmp8 = bitcast i32* %tmp to i8*
+        %p0 = getelementptr i8* %tmp8, i32 0
+        %p1 = getelementptr i8* %tmp8, i32 1
+        %p2 = getelementptr i8* %tmp8, i32 2
+        %p3 = getelementptr i8* %tmp8, i32 3
+        store i8 %d, i8* %p0
+        store i8 %c, i8* %p1
+        store i8 %b, i8* %p2
+        store i8 %a, i8* %p3
+        %concat = load i32* %tmp
+        ret i32 %concat
+}
+
+define i64 @util_make_concat8(i8 %a, i8 %b, i8 %c, i8 %d, 
+                              i8 %e, i8 %f, i8 %g, i8 %h) {
+        %tmp = alloca i64
+        %tmp8 = bitcast i64* %tmp to i8*
+        %p0 = getelementptr i8* %tmp8, i32 0
+        %p1 = getelementptr i8* %tmp8, i32 1
+        %p2 = getelementptr i8* %tmp8, i32 2
+        %p3 = getelementptr i8* %tmp8, i32 3
+        %p4 = getelementptr i8* %tmp8, i32 4
+        %p5 = getelementptr i8* %tmp8, i32 5
+        %p6 = getelementptr i8* %tmp8, i32 6
+        %p7 = getelementptr i8* %tmp8, i32 7
+        store i8 %h, i8* %p0
+        store i8 %g, i8* %p1
+        store i8 %f, i8* %p2
+        store i8 %e, i8* %p3
+        store i8 %d, i8* %p4
+        store i8 %c, i8* %p5
+        store i8 %b, i8* %p6
+        store i8 %a, i8* %p7
+        %concat = load i64* %tmp
+        ret i64 %concat
+}
+
+define i32 @util_make_select(i32 %cond, i32 %t, i32 %f) {
+        %cond_i1 = icmp ne i32 %cond, 0
+        %res = select i1 %cond_i1, i32 %t, i32 %f
+        ret i32 %res
+}
\ No newline at end of file
diff --git a/test/Feature/const_array_opt1.c b/test/Feature/const_array_opt1.c
new file mode 100644
index 00000000..96c46fb9
--- /dev/null
+++ b/test/Feature/const_array_opt1.c
@@ -0,0 +1,37 @@
+// RUN: %llvmgcc %s -emit-llvm -O0 -c -o %t.bc
+// RUN: %klee --const-array-opt --max-time=10 --only-output-states-covering-new %t.bc >%t.log
+// grep -q "Finished successfully!\n"
+
+/* This is testing the const array optimization.  On my 2.3GHz machine
+   this takes under 2 seconds w/ the optimization and almost 6 minutes
+   w/o.  So we kill it in 10 sec and check if it has finished
+   successfully. */
+
+#include <unistd.h>
+#include <assert.h>
+#include <stdio.h>
+  
+int main() {
+#define N 8192
+#define N_IDX 16
+  unsigned char a[N];
+  unsigned i, k[N_IDX];
+
+  for (i=0; i<N; i++)
+    a[i] = i % 256;
+  
+  klee_make_symbolic_name(k, sizeof(k), "k");
+  
+  for (i=0; i<N_IDX; i++) {
+    if (k[i] >= N)
+      klee_silent_exit(0);
+
+    if (a[k[i]] == i)
+      assert(k[i] % 256 == i);
+    else klee_silent_exit(0);
+  }
+
+  printf("Finished successfully!\n");
+
+  return 0;
+}
diff --git a/test/Feature/dg.exp b/test/Feature/dg.exp
new file mode 100644
index 00000000..879685ca
--- /dev/null
+++ b/test/Feature/dg.exp
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,llx,c,cpp,tr}]]
diff --git a/test/Feature/utils.h b/test/Feature/utils.h
new file mode 100644
index 00000000..5423a0dc
--- /dev/null
+++ b/test/Feature/utils.h
@@ -0,0 +1,16 @@
+typedef unsigned char uint8_t;
+typedef unsigned short uint16_t;
+typedef unsigned int uint32_t;
+typedef unsigned long long uint64_t;
+
+uint32_t util_make_and_i1(uint32_t a, uint32_t b);
+uint32_t util_make_or_i1(uint32_t a, uint32_t b);
+
+uint16_t util_make_concat2(uint8_t a, uint8_t b);
+uint32_t util_make_concat4(uint8_t a, uint8_t b, 
+                           uint8_t c, uint8_t d);
+uint64_t util_make_concat8(uint8_t a, uint8_t b,
+                           uint8_t c, uint8_t d,
+                           uint8_t e, uint8_t f,
+                           uint8_t g, uint8_t h);
+uint32_t util_make_select(uint32_t cond, uint32_t true, uint32_t false);