From eedc49570c3ed3111b2a2a11a7861ac90ab650f8 Mon Sep 17 00:00:00 2001 From: Timotej Kapus Date: Sat, 9 Nov 2019 17:34:50 +0000 Subject: [optimize-array] Hash collision test --- unittests/Expr/ArrayExprTest.cpp | 75 ++++++++++++++++++++++++++++++++++++++++ unittests/Expr/CMakeLists.txt | 5 +-- 2 files changed, 78 insertions(+), 2 deletions(-) create mode 100644 unittests/Expr/ArrayExprTest.cpp (limited to 'unittests') diff --git a/unittests/Expr/ArrayExprTest.cpp b/unittests/Expr/ArrayExprTest.cpp new file mode 100644 index 00000000..47375abd --- /dev/null +++ b/unittests/Expr/ArrayExprTest.cpp @@ -0,0 +1,75 @@ +//===-- ExprTest.cpp ------------------------------------------------------===// +// +// The KLEE Symbolic Virtual Machine +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "gtest/gtest.h" +#include + +#include "../../lib/Expr/ArrayExprOptimizer.h" +#include "klee/Expr/ArrayCache.h" +#include "klee/Expr/Assignment.h" +#include "klee/Expr/Expr.h" +#include + +using namespace klee; +namespace klee { +extern llvm::cl::opt OptimizeArray; +} + +namespace { + +ref getConstant(int value, Expr::Width width) { + int64_t ext = value; + uint64_t trunc = ext & (((uint64_t)-1LL) >> (64 - width)); + return ConstantExpr::create(trunc, width); +} + +static ArrayCache ac; + +TEST(ArrayExprTest, HashCollisions) { + klee::OptimizeArray = ALL; + std::vector> constVals(256, + ConstantExpr::create(5, Expr::Int8)); + const Array *array = ac.CreateArray("arr0", 256, constVals.data(), + constVals.data() + constVals.size(), + Expr::Int32, Expr::Int8); + const Array *symArray = ac.CreateArray("symIdx", 4); + ref symIdx = Expr::createTempRead(symArray, Expr::Int32); + UpdateList ul(array, 0); + ul.extend(getConstant(3, Expr::Int32), getConstant(11, Expr::Int8)); + ref firstRead = ReadExpr::create(ul, symIdx); + ul.extend(getConstant(6, Expr::Int32), getConstant(42, Expr::Int8)); + ul.extend(getConstant(6, Expr::Int32), getConstant(42, Expr::Int8)); + ref updatedRead = ReadExpr::create(ul, symIdx); + + // This test requires hash collision and should be updated if the hash + // function changes + ASSERT_NE(updatedRead, firstRead); + ASSERT_EQ(updatedRead->hash(), firstRead->hash()); + + std::vector value = {6, 0, 0, 0}; + std::vector> values = {value}; + std::vector assigmentArrays = {symArray}; + auto a = std::make_unique(assigmentArrays, values, + /*_allowFreeValues=*/true); + + EXPECT_NE(a->evaluate(updatedRead), a->evaluate(firstRead)); + EXPECT_EQ(a->evaluate(updatedRead), getConstant(42, Expr::Int8)); + EXPECT_EQ(a->evaluate(firstRead), getConstant(5, Expr::Int8)); + + ExprOptimizer opt; + auto oFirstRead = opt.optimizeExpr(firstRead, true); + auto oUpdatedRead = opt.optimizeExpr(updatedRead, true); + EXPECT_NE(oFirstRead, firstRead); + EXPECT_NE(updatedRead, oUpdatedRead); + + EXPECT_NE(a->evaluate(oUpdatedRead), a->evaluate(oFirstRead)); + EXPECT_EQ(a->evaluate(oUpdatedRead), getConstant(42, Expr::Int8)); + EXPECT_EQ(a->evaluate(oFirstRead), getConstant(5, Expr::Int8)); +} +} diff --git a/unittests/Expr/CMakeLists.txt b/unittests/Expr/CMakeLists.txt index 84dce619..34bc5a01 100644 --- a/unittests/Expr/CMakeLists.txt +++ b/unittests/Expr/CMakeLists.txt @@ -1,3 +1,4 @@ add_klee_unit_test(ExprTest - ExprTest.cpp) -target_link_libraries(ExprTest PRIVATE kleaverExpr) + ExprTest.cpp + ArrayExprTest.cpp) +target_link_libraries(ExprTest PRIVATE kleaverExpr kleeSupport kleaverSolver) -- cgit 1.4.1