File 0012-Fix-test-cases-to-support-opaque-pointers.patch of Package klee
From: Martin Nowack <m.nowack@imperial.ac.uk>
Date: Mon, 30 Oct 2023 14:48:58 +0000
Subject: Fix test cases to support opaque pointers
Patch-mainline: no
References: llvm16
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
---
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 <stdarg.h>
#include <assert.h>
#include <stdio.h>
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 <assert.h>
+#include <stdarg.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);
+}
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
}
--
2.43.0