diff options
author | Cristian Cadar <c.cadar@imperial.ac.uk> | 2020-04-05 19:03:45 +0100 |
---|---|---|
committer | MartinNowack <2443641+MartinNowack@users.noreply.github.com> | 2020-06-19 18:19:53 +0100 |
commit | fbd077c1c594ac1cacbd63e40597d0099c426e34 (patch) | |
tree | ec6a54adb85688406aa846bccbd1593d9572d64d | |
parent | 32b5c245f00bf79ab604fd7473d880fbd3e37890 (diff) | |
download | klee-fbd077c1c594ac1cacbd63e40597d0099c426e34.tar.gz |
Added test checking that KLEE correctly handles variadic arguments with the byval attribute
-rw-r--r-- | test/Feature/VarArgByVal.c | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/test/Feature/VarArgByVal.c b/test/Feature/VarArgByVal.c new file mode 100644 index 00000000..43c815b5 --- /dev/null +++ b/test/Feature/VarArgByVal.c @@ -0,0 +1,128 @@ +/* This test checks that KLEE correctly handles variadic arguments with the + byval attribute */ + +// RUN: %clang %s -emit-llvm %O0opt -c -g -o %t1.bc +// RUN: rm -rf %t.klee-out +// RUN: %klee --exit-on-error --output-dir=%t.klee-out %t1.bc +// RUN FileCheck %s klee-last/assembly.ll +// CHECK: @test(i32 -1, %struct.bar* byval + +#include <stdarg.h> +#include <assert.h> +#include <stdio.h> + +struct foo { + char f1; + long long f2; + long long f3; + char f4; + long f5; + int f6; + char f7; +}; + +struct bar { + long long int f1; + char f2; + long long f3; + char f4; + long f5; +}; + +struct foo test1(int x, ...) { + va_list ap; + va_start(ap, x); + assert(x == -1); + + struct foo f = va_arg(ap, struct foo); + assert(f.f1 == 1); + assert(f.f2 == 2); + assert(f.f3 == 3); + assert(f.f4 == 4); + assert(f.f5 == 5); + assert(f.f6 == 6); + assert(f.f7 == 7); + + struct bar b = va_arg(ap, struct bar); + assert(b.f1 == 11); + assert(b.f2 == 12); + assert(b.f3 == 13); + assert(b.f4 == 14); + assert(b.f5 == 15); + + va_end(ap); + + f.f1++; + return f; +} + +struct foo test2(int x, long long int l, ...) { + va_list ap; + va_start(ap, l); + assert(x == 10); + assert(l == 1000); + + int i = va_arg(ap, int); + assert(i == 10); + + struct foo f = va_arg(ap, struct foo); + assert(f.f1 == 1); + assert(f.f2 == 2); + assert(f.f3 == 3); + assert(f.f4 == 4); + assert(f.f5 == 5); + assert(f.f6 == 6); + assert(f.f7 == 7); + + l = va_arg(ap, long long int); + assert(l == 1000); + + struct bar b = va_arg(ap, struct bar); + assert(b.f1 == 11); + assert(b.f2 == 12); + assert(b.f3 == 13); + assert(b.f4 == 14); + assert(b.f5 == 15); + + f = va_arg(ap, struct foo); + assert(f.f1 == 10); + assert(f.f2 == 20); + assert(f.f3 == 30); + assert(f.f4 == 40); + assert(f.f5 == 50); + assert(f.f6 == 60); + assert(f.f7 == 70); + + b = va_arg(ap, struct bar); + assert(b.f1 == 1); + assert(b.f2 == 3); + assert(b.f3 == 5); + assert(b.f4 == 7); + assert(b.f5 == 9); + + va_end(ap); + + f.f1++; + return f; +} + +int main() { + struct foo f = { 1, 2, 3, 4, 5, 6, 7 }; + struct bar b = { 11, 12, 13, 14, 15 }; + struct foo res = test1(-1, f, b); + assert(res.f1 == 2); + assert(res.f2 == 2); + assert(res.f3 == 3); + assert(res.f4 == 4); + assert(res.f5 == 5); + assert(res.f6 == 6); + assert(res.f7 == 7); + // check that f was not modified, as it's passed by value + assert(f.f1 == 1); + + int i = 10; + long long int l = 1000; + struct foo f2 = { 10, 20, 30, 40, 50, 60, 70 }; + struct bar b2 = { 1, 3, 5, 7, 9 }; + test2(i, l, i, f, l, b, f2, b2); +} |