diff options
-rw-r--r-- | lib/Expr/Expr.cpp | 3 | ||||
-rw-r--r-- | test/Feature/LargeReturnTypes.cpp | 27 |
2 files changed, 28 insertions, 2 deletions
diff --git a/lib/Expr/Expr.cpp b/lib/Expr/Expr.cpp index e02a7e49..c9754765 100644 --- a/lib/Expr/Expr.cpp +++ b/lib/Expr/Expr.cpp @@ -300,14 +300,13 @@ void Expr::dump() const { ref<Expr> ConstantExpr::fromMemory(void *address, Width width) { switch (width) { - default: assert(0 && "invalid type"); case Expr::Bool: return ConstantExpr::create(*(( uint8_t*) address), width); case Expr::Int8: return ConstantExpr::create(*(( uint8_t*) address), width); case Expr::Int16: return ConstantExpr::create(*((uint16_t*) address), width); case Expr::Int32: return ConstantExpr::create(*((uint32_t*) address), width); case Expr::Int64: return ConstantExpr::create(*((uint64_t*) address), width); // FIXME: what about machines without x87 support? - case Expr::Fl80: + default: return ConstantExpr::alloc(llvm::APInt(width, (width+llvm::integerPartWidth-1)/llvm::integerPartWidth, (const uint64_t*)address)); diff --git a/test/Feature/LargeReturnTypes.cpp b/test/Feature/LargeReturnTypes.cpp new file mode 100644 index 00000000..caa345fc --- /dev/null +++ b/test/Feature/LargeReturnTypes.cpp @@ -0,0 +1,27 @@ +// RUN: %llvmgxx -g -fno-exceptions -emit-llvm -O0 -c -o %t.bc %s +// RUN: %klee --libc=klee --no-output --exit-on-error %t.bc > %t.log + +/* Tests the ability to call external functions which return large values + * (i.e. structs). In this test case, fstream::ftellg() returns a + * streampos (an {i64, i64} pair) which is implicitly converted to a size_t. */ + +#include <fstream> + +using namespace std; + +size_t fileSize(const char *filename) { + fstream f(filename, fstream::in | fstream::binary); + + if (f.is_open()) { + f.seekg(0, fstream::end); + size_t fileSize = f.tellg(); + return fileSize; + } + + return (size_t) -1; +} + +int main(void) { + size_t size = fileSize("/bin/sh"); + return (size != (size_t) -1) ? 0 : 1; +} |