From 670ea6b70d2ee0a998f05624cbef041a489450b3 Mon Sep 17 00:00:00 2001 From: Martin Nowack Date: Mon, 30 Oct 2023 14:48:58 +0000 Subject: Fix test cases to support opaque pointers --- test/CXX/LandingPad.cpp | 2 + test/Concrete/CMakeLists.txt | 4 ++ test/Feature/KleeStats.c | 2 +- test/Feature/VarArgByVal.c | 8 +-- test/Feature/VarArgByValOld.c | 131 ++++++++++++++++++++++++++++++++++++++++++ test/Feature/asm_lifting.ll | 2 +- 6 files changed, 143 insertions(+), 6 deletions(-) create mode 100644 test/Feature/VarArgByValOld.c diff --git a/test/CXX/LandingPad.cpp b/test/CXX/LandingPad.cpp index 18cad7c8..6b6e6748 100644 --- a/test/CXX/LandingPad.cpp +++ b/test/CXX/LandingPad.cpp @@ -1,3 +1,5 @@ +// REQUIRES: lt-llvm-15.0 +// Different LLVM IR syntax with opaque ptr - it's a nullptr directly, no constant // RUN: %clangxx %s -emit-llvm -c -o %t1.bc // RUN: rm -rf %t.klee-out // RUN: %klee --output-dir=%t.klee-out %t1.bc 2>&1 | FileCheck %s diff --git a/test/Concrete/CMakeLists.txt b/test/Concrete/CMakeLists.txt index e7cf2416..a073482c 100644 --- a/test/Concrete/CMakeLists.txt +++ b/test/Concrete/CMakeLists.txt @@ -8,4 +8,8 @@ #===------------------------------------------------------------------------===# set(OZERO_OPT "-O0 -Xclang -disable-O0-optnone") +if ("${LLVM_VERSION_MAJOR}" EQUAL 15) + set(LLVM_AS_FLAGS "-opaque-pointers") + set(LLVM_LINK_FLAGS "-opaque-pointers") +endif () configure_file(Makefile.cmake.test.in Makefile.cmake.test @ONLY) diff --git a/test/Feature/KleeStats.c b/test/Feature/KleeStats.c index 2a498beb..8045f22e 100644 --- a/test/Feature/KleeStats.c +++ b/test/Feature/KleeStats.c @@ -29,7 +29,7 @@ int main(){ // First check we find a line with the expected format // CHECK-STATS: Path,Instrs,Time(s),ICov(%),BCov(%),ICount,TSolver(%),ActiveStates,MaxActiveStates,Mem(MiB),MaxMem(MiB) // Check there is a line with .klee-out dir, non zero instruction, less than 1 second execution time and 100 ICov. -// CHECK-STATS: {{.*\.klee-out,[1-9]+,[0-9]+\.([0-9]+),100\.00}} +// CHECK-STATS: {{.*\.klee-out,[1-9][0-9]+,[0-9]+\.([0-9]+),100\.00}} // Check other formats // CHECK-STATS-ABS-TIMES: Path,Time(s),TUser(s),TResolve(s),TCex(s),TSolver(s),TFork(s) diff --git a/test/Feature/VarArgByVal.c b/test/Feature/VarArgByVal.c index 551e6c63..7b979f61 100644 --- a/test/Feature/VarArgByVal.c +++ b/test/Feature/VarArgByVal.c @@ -1,4 +1,5 @@ -/* This test checks that KLEE correctly handles variadic arguments with the +// REQUIRES: geq-llvm-15.0 +/* This test checks that KLEE correctly handles variadic arguments with the byval attribute */ // RUN: %clang %s -emit-llvm %O0opt -c -g -o %t1.bc @@ -7,9 +8,8 @@ // RUN: FileCheck %s --input-file=%t.klee-out/assembly.ll // // TODO: Make noundef unconditional when LLVM 14 is the oldest supported version. -// CHECK: @test1({{.*}}, i32 {{(noundef )?}}-1, %struct.foo* {{(noundef )?}}byval{{.*}} %struct.bar* {{(noundef )?}}byval -// CHECK: @test2({{.*}}, %struct.foo* {{(noundef )?}}byval{{.*}} %struct.bar* {{(noundef )?}}byval - +// CHECK: call void (ptr, i32, ...) @test1(ptr sret(%struct.foo) align 8 {{.*}}, i32 noundef -1, ptr noundef byval(%struct.foo) align 8 {{.*}}, ptr noundef byval(%struct.bar) align 8 {{.*}}) +// CHECK: call void (ptr, i32, i64, ...) @test2(ptr sret(%struct.foo) align 8 %tmp, i32 noundef {{.*}}, i64 noundef {{.*}}, i32 noundef {{.*}}, ptr noundef byval(%struct.foo) align 8 {{.*}}, i64 noundef {{.*}}, ptr noundef byval(%struct.bar) align 8 {{.*}}, ptr noundef byval(%struct.foo) align 8 {{.*}}, ptr noundef byval(%struct.bar) align 8 {{.*}}) #include #include #include diff --git a/test/Feature/VarArgByValOld.c b/test/Feature/VarArgByValOld.c new file mode 100644 index 00000000..011046d8 --- /dev/null +++ b/test/Feature/VarArgByValOld.c @@ -0,0 +1,131 @@ +// REQUIRES: lt-llvm-15.0 +/* 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 --input-file=%t.klee-out/assembly.ll +// +// TODO: Make noundef unconditional when LLVM 14 is the oldest supported version. +// CHECK: @test1({{.*}}, i32 {{(noundef )?}}-1, %struct.foo* {{(noundef )?}}byval{{.*}} %struct.bar* {{(noundef )?}}byval +// CHECK: @test2({{.*}}, %struct.foo* {{(noundef )?}}byval{{.*}} %struct.bar* {{(noundef )?}}byval +#include +#include +#include + +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); +} diff --git a/test/Feature/asm_lifting.ll b/test/Feature/asm_lifting.ll index d99db0cf..115bc2f9 100644 --- a/test/Feature/asm_lifting.ll +++ b/test/Feature/asm_lifting.ll @@ -17,7 +17,7 @@ entry: %1 = getelementptr inbounds [47 x i8], [47 x i8]* %0, i64 0, i64 0 ; Make sure memory barrier with function arguments is kept %2 = call i8* asm sideeffect "", "=r,0,~{memory},~{dirflag},~{fpsr},~{flags}"(i8* nonnull %1) - ; CHECK: %2 = call i8* asm sideeffect "", "=r,0,~{memory},~{dirflag},~{fpsr},~{flags}"(i8* nonnull %1) + ; CHECK: %2 = call {{.*}} asm sideeffect "", "=r,0,~{memory},~{dirflag},~{fpsr},~{flags}"({{.*}} nonnull %1) ret i32 0 } -- cgit 1.4.1