//===-- 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 #include "gtest/gtest.h" #include "klee/Expr.h" #include "klee/util/ArrayCache.h" using namespace klee; 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); } TEST(ExprTest, BasicConstruction) { EXPECT_EQ(ref(ConstantExpr::alloc(0, 32)), SubExpr::create(ConstantExpr::alloc(10, 32), ConstantExpr::alloc(10, 32))); } TEST(ExprTest, ConcatExtract) { ArrayCache ac; const Array *array = ac.CreateArray("arr0", 256); ref read8 = Expr::createTempRead(array, 8); const Array *array2 = ac.CreateArray("arr1", 256); ref read8_2 = Expr::createTempRead(array2, 8); ref c100 = getConstant(100, 8); ref concat1 = ConcatExpr::create4(read8, read8, c100, read8_2); EXPECT_EQ(2U, concat1->getNumKids()); EXPECT_EQ(2U, concat1->getKid(1)->getNumKids()); EXPECT_EQ(2U, concat1->getKid(1)->getKid(1)->getNumKids()); ref extract1 = ExtractExpr::create(concat1, 8, 16); EXPECT_EQ(Expr::Concat, extract1->getKind()); EXPECT_EQ(read8, extract1->getKid(0)); EXPECT_EQ(c100, extract1->getKid(1)); ref extract2 = ExtractExpr::create(concat1, 6, 26); EXPECT_EQ( Expr::Concat, extract2->getKind()); EXPECT_EQ( read8, extract2->getKid(0)); EXPECT_EQ( Expr::Concat, extract2->getKid(1)->getKind()); EXPECT_EQ( read8, extract2->getKid(1)->getKid(0)); EXPECT_EQ( Expr::Concat, extract2->getKid(1)->getKid(1)->getKind()); EXPECT_EQ( c100, extract2->getKid(1)->getKid(1)->getKid(0)); EXPECT_EQ( Expr::Extract, extract2->getKid(1)->getKid(1)->getKid(1)->getKind()); ref extract3 = ExtractExpr::create(concat1, 24, 1); EXPECT_EQ(Expr::Extract, extract3->getKind()); ref extract4 = ExtractExpr::create(concat1, 27, 2); EXPECT_EQ(Expr::Extract, extract4->getKind()); const ExtractExpr* tmp = cast(extract4); EXPECT_EQ(3U, tmp->offset); EXPECT_EQ(2U, tmp->getWidth()); ref extract5 = ExtractExpr::create(concat1, 17, 5); EXPECT_EQ(Expr::Extract, extract5->getKind()); ref extract6 = ExtractExpr::create(concat1, 3, 26); EXPECT_EQ(Expr::Concat, extract6->getKind()); EXPECT_EQ(Expr::Extract, extract6->getKid(0)->getKind()); EXPECT_EQ(Expr::Concat, extract6->getKid(1)->getKind()); EXPECT_EQ(read8, extract6->getKid(1)->getKid(0)); EXPECT_EQ(Expr::Concat, extract6->getKid(1)->getKid(1)->getKind()); EXPECT_EQ(c100, extract6->getKid(1)->getKid(1)->getKid(0)); EXPECT_EQ(Expr::Extract, extract6->getKid(1)->getKid(1)->getKid(1)->getKind()); ref concat10 = ConcatExpr::create4(read8, c100, c100, read8); ref extract10 = ExtractExpr::create(concat10, 8, 16); EXPECT_EQ(Expr::Constant, extract10->getKind()); } TEST(ExprTest, ExtractConcat) { ArrayCache ac; const Array *array = ac.CreateArray("arr2", 256); ref read64 = Expr::createTempRead(array, 64); const Array *array2 = ac.CreateArray("arr3", 256); ref read8_2 = Expr::createTempRead(array2, 8); ref extract1 = ExtractExpr::create(read64, 36, 4); ref extract2 = ExtractExpr::create(read64, 32, 4); ref extract3 = ExtractExpr::create(read64, 12, 3); ref extract4 = ExtractExpr::create(read64, 10, 2); ref extract5 = ExtractExpr::create(read64, 2, 8); ref kids1[6] = { extract1, extract2, read8_2, extract3, extract4, extract5 }; ref concat1 = ConcatExpr::createN(6, kids1); EXPECT_EQ(29U, concat1->getWidth()); ref extract6 = ExtractExpr::create(read8_2, 2, 5); ref extract7 = ExtractExpr::create(read8_2, 1, 1); ref kids2[3] = { extract1, extract6, extract7 }; ref concat2 = ConcatExpr::createN(3, kids2); EXPECT_EQ(10U, concat2->getWidth()); EXPECT_EQ(Expr::Extract, concat2->getKid(0)->getKind()); EXPECT_EQ(Expr::Extract, concat2->getKid(1)->getKind()); } }