Hello community, here is the log from the commit of package klee for openSUSE:Factory checked in at 2019-11-04 17:15:53 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/klee (Old) and /work/SRC/openSUSE:Factory/.klee.new.2990 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "klee" Mon Nov 4 17:15:53 2019 rev:18 rq:745088 version:2.0+20191031 Changes: -------- --- /work/SRC/openSUSE:Factory/klee/klee.changes 2019-10-04 16:07:17.104620091 +0200 +++ /work/SRC/openSUSE:Factory/.klee.new.2990/klee.changes 2019-11-04 17:16:01.316877481 +0100 @@ -1,0 +2,21 @@ +Mon Nov 04 06:50:43 UTC 2019 - [email protected] + +- switch to llvm 9 +- Update to version 2.0+20191031: + * Executor: fix missing default case in switch instruction + * enable testing for LLVM 9.0 + * LLVM 9.0: fourth parameter for @llvm.objectsize() + * klee-libc: add bcmp + * support compilation against LLVM 9.0 + * [klee-replay] Fix relative executable paths + * ExecutorTimers: refactor and move to support lib + * ExecutorTimers: remove signalling, fix endless looping fork + * Executor.h: remove defined functions without implementation + * test/Expr/Evaluate2.kquery: add link to issue + * fix: make llvm 7.1 known + * test/Feature/SolverTimeout.c: re-enable for Z3 + * test/lit.cfg: test if current version is known + * test/lit.cfg: use lit_config instead of lit + * Do not use klee_range() in regression/2014-09-13-debug-info.c test, as it is incompatible with klee_prefer_cex. Fixes https://github.com/klee/klee/issues/1161 + +------------------------------------------------------------------- Old: ---- klee-2.0+20190920.tar.xz New: ---- klee-2.0+20191031.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ klee.spec ++++++ --- /var/tmp/diff_new_pack.k5bjxt/_old 2019-11-04 17:16:02.912879186 +0100 +++ /var/tmp/diff_new_pack.k5bjxt/_new 2019-11-04 17:16:02.936879212 +0100 @@ -16,11 +16,11 @@ # -%define llvm_version_major 8 +%define llvm_version_major 9 %define llvm_version_minor 0 %define llvm_version %{llvm_version_major} -%define version_unconverted 2.0+20190920 +%define version_unconverted 2.0+20191031 %ifarch %{ix86} x86_64 %define with_uclibc 1 @@ -32,7 +32,7 @@ Summary: LLVM Execution Engine License: NCSA Group: Development/Languages/Other -Version: 2.0+20190920 +Version: 2.0+20191031 Release: 0 Url: http://klee.github.io/ Source0: %{name}-%{version}.tar.xz ++++++ FileCheck.cpp ++++++ --- /var/tmp/diff_new_pack.k5bjxt/_old 2019-11-04 17:16:03.156879447 +0100 +++ /var/tmp/diff_new_pack.k5bjxt/_new 2019-11-04 17:16:03.168879460 +0100 @@ -1,9 +1,8 @@ //===- FileCheck.cpp - Check that File's Contents match what is expected --===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -22,6 +21,7 @@ #include "llvm/Support/WithColor.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/FileCheck.h" +#include <cmath> using namespace llvm; static cl::opt<std::string> @@ -80,13 +80,16 @@ "provided for convenience as old tests are migrated to the new\n" "non-overlapping CHECK-DAG implementation.\n")); -static cl::opt<bool> Verbose("v", cl::init(false), - cl::desc("Print directive pattern matches.\n")); +static cl::opt<bool> Verbose( + "v", cl::init(false), + cl::desc("Print directive pattern matches, or add them to the input dump\n" + "if enabled.\n")); static cl::opt<bool> VerboseVerbose( "vv", cl::init(false), cl::desc("Print information helpful in diagnosing internal FileCheck\n" - "issues. Implies -v.\n")); + "issues, or add it to the input dump if enabled. Implies\n" + "-v.\n")); static const char * DumpInputEnv = "FILECHECK_DUMP_INPUT_ON_FAILURE"; static cl::opt<bool> DumpInputOnFailure( @@ -403,7 +406,7 @@ unsigned LineCount = InputFileText.count('\n'); if (InputFileEnd[-1] != '\n') ++LineCount; - unsigned LineNoWidth = log10(LineCount) + 1; + unsigned LineNoWidth = std::log10(LineCount) + 1; // +3 below adds spaces (1) to the left of the (right-aligned) line numbers // on input lines and (2) to the right of the (left-aligned) labels on // annotation lines so that input lines and annotation lines are more @@ -534,8 +537,8 @@ continue; } if (EqIdx == 0) { - errs() << "Missing pattern variable name in command-line definition '-D" - << G << "'\n"; + errs() << "Missing variable name in command-line definition '-D" << G + << "'\n"; GlobalDefineError = true; continue; } ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.k5bjxt/_old 2019-11-04 17:16:03.352879656 +0100 +++ /var/tmp/diff_new_pack.k5bjxt/_new 2019-11-04 17:16:03.372879678 +0100 @@ -1,4 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">git://github.com/klee/klee.git</param> - <param name="changesrevision">0aed7731210d0eb41c0ea767edb8067130cf6252</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">2b0b0f89fcfff828b6dd8c20f58d872c7395dba4</param></service></servicedata> \ No newline at end of file ++++++ klee-2.0+20190920.tar.xz -> klee-2.0+20191031.tar.xz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/.travis.yml new/klee-2.0+20191031/.travis.yml --- old/klee-2.0+20190920/.travis.yml 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/.travis.yml 2019-10-31 16:38:21.000000000 +0100 @@ -12,7 +12,7 @@ ########################################################################### # Check a subset of the matrix of: - # LLVM : {3.8, 3.9, 4.0, 5.0, 6.0, 7} + # LLVM : {3.8, 3.9, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0} # SOLVERS : {Z3, STP, STP:Z3, metaSMT} # STP_VERSION : {2.3.3, master} # METASMT_VERSION : {v4.rc1} @@ -56,6 +56,7 @@ matrix: # Check supported LLVM versions + - LLVM_VERSION=9.0 - LLVM_VERSION=8.0 - LLVM_VERSION=7.0 - LLVM_VERSION=6.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/Dockerfile new/klee-2.0+20191031/Dockerfile --- old/klee-2.0+20190920/Dockerfile 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/Dockerfile 2019-10-31 16:38:21.000000000 +0100 @@ -39,7 +39,7 @@ # TODO remove adding sudo package # Create ``klee`` user for container with password ``klee``. # and give it password-less sudo access (temporarily so we can use the TravisCI scripts) -RUN apt update && apt -y --no-install-recommends install sudo emacs vim && \ +RUN apt update && apt -y --no-install-recommends install sudo emacs vim file && \ rm -rf /var/lib/apt/lists/* && \ useradd -m klee && \ echo klee:klee | chpasswd && \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/include/klee/Internal/Support/Timer.h new/klee-2.0+20191031/include/klee/Internal/Support/Timer.h --- old/klee-2.0+20190920/include/klee/Internal/Support/Timer.h 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/include/klee/Internal/Support/Timer.h 2019-10-31 16:38:21.000000000 +0100 @@ -12,16 +12,85 @@ #include "klee/Internal/System/Time.h" +#include "llvm/ADT/SmallVector.h" + +#include <functional> +#include <memory> + namespace klee { + + /** + * A WallTimer stores its creation time. + */ class WallTimer { - time::Point start; - + const time::Point start; public: WallTimer(); - /// check - Return the delta since the timer was created - time::Span check(); + /// Return the delta since the timer was created + time::Span delta() const; + }; + + + /** + * A Timer repeatedly executes a `callback` after a specified `interval`. + * An object of this class is _passive_ and only keeps track of the next invocation time. + * _Passive_ means, that it has to be `invoke`d by an external caller with the current time. + * Only when the time span between the current time and the last invocation exceeds the + * specified `interval`, the `callback` will be executed. + * Multiple timers are typically managed by a TimerGroup. + */ + class Timer { + /// Approximate interval between callback invocations. + time::Span interval; + /// Wall time for next invocation. + time::Point nextInvocationTime; + /// The event callback. + std::function<void()> run; + public: + /// \param interval The time span between callback invocations. + /// \param callback The event callback. + Timer(const time::Span &interval, std::function<void()> &&callback); + + /// Return specified `interval` between invocations. + time::Span getInterval() const; + /// Execute `callback` if invocation time exceeded. + void invoke(const time::Point ¤tTime); + /// Set new invocation time to `currentTime + interval`. + void reset(const time::Point ¤tTime); + }; + + + /** + * A TimerGroup manages multiple timers. + * + * TimerGroup simplifies the handling of multiple Timer objects by offering a unifying + * Timer-like interface. Additionally, it serves as a barrier and prevents timers from + * being invoked too often by defining a minimum invocation interval (MI). + * All registered timer intervals should be larger than MI and also be multiples of MI. + * Similar to Timer, a TimerGroup is _passive_ and needs to be `invoke`d by an external + * caller. + */ + class TimerGroup { + /// Registered timers. + llvm::SmallVector<std::unique_ptr<Timer>, 4> timers; + /// Timer that invokes all registered timers after minimum interval. + Timer invocationTimer; + /// Time of last `invoke` call. + time::Point currentTime; + public: + /// \param minInterval The minimum interval between invocations of registered timers. + explicit TimerGroup(const time::Span &minInterval); + + /// Add a timer to be executed periodically. + /// + /// \param timer The timer object to register. + void add(std::unique_ptr<Timer> timer); + /// Invoke registered timers with current time only if minimum interval exceeded. + void invoke(); + /// Reset all timers. + void reset(); }; -} +} // klee #endif /* KLEE_TIMER_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/include/klee/TimerStatIncrementer.h new/klee-2.0+20191031/include/klee/TimerStatIncrementer.h --- old/klee-2.0+20190920/include/klee/TimerStatIncrementer.h 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/include/klee/TimerStatIncrementer.h 2019-10-31 16:38:21.000000000 +0100 @@ -14,19 +14,23 @@ #include "klee/Internal/Support/Timer.h" namespace klee { + + /** + * A TimerStatIncrementer adds its lifetime to a specified Statistic. + */ class TimerStatIncrementer { private: - WallTimer timer; + const WallTimer timer; Statistic &statistic; public: - TimerStatIncrementer(Statistic &_statistic) : statistic(_statistic) {} + explicit TimerStatIncrementer(Statistic &statistic) : statistic(statistic) {} ~TimerStatIncrementer() { // record microseconds - statistic += timer.check().toMicroseconds(); + statistic += timer.delta().toMicroseconds(); } - time::Span check() { return timer.check(); } + time::Span delta() const { return timer.delta(); } }; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/lib/Core/AddressSpace.cpp new/klee-2.0+20191031/lib/Core/AddressSpace.cpp --- old/klee-2.0+20190920/lib/Core/AddressSpace.cpp 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/lib/Core/AddressSpace.cpp 2019-10-31 16:38:21.000000000 +0100 @@ -237,7 +237,7 @@ while (oi != begin) { --oi; const MemoryObject *mo = oi->first; - if (timeout && timeout < timer.check()) + if (timeout && timeout < timer.delta()) return true; int incomplete = @@ -256,7 +256,7 @@ // search forwards for (oi = start; oi != end; ++oi) { const MemoryObject *mo = oi->first; - if (timeout && timeout < timer.check()) + if (timeout && timeout < timer.delta()) return true; bool mustBeTrue; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/lib/Core/CMakeLists.txt new/klee-2.0+20191031/lib/Core/CMakeLists.txt --- old/klee-2.0+20190920/lib/Core/CMakeLists.txt 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/lib/Core/CMakeLists.txt 2019-10-31 16:38:21.000000000 +0100 @@ -14,7 +14,6 @@ CoreStats.cpp ExecutionState.cpp Executor.cpp - ExecutorTimers.cpp ExecutorUtil.cpp ExternalDispatcher.cpp ImpliedValue.cpp diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/lib/Core/Executor.cpp new/klee-2.0+20191031/lib/Core/Executor.cpp --- old/klee-2.0+20190920/lib/Core/Executor.cpp 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/lib/Core/Executor.cpp 2019-10-31 16:38:21.000000000 +0100 @@ -12,7 +12,6 @@ #include "../Expr/ArrayExprOptimizer.h" #include "Context.h" #include "CoreStats.h" -#include "ExecutorTimerInfo.h" #include "ExternalDispatcher.h" #include "ImpliedValue.h" #include "Memory.h" @@ -104,6 +103,13 @@ cl::OptionCategory TestGenCat("Test generation options", "These options impact test generation."); + +cl::opt<std::string> MaxTime( + "max-time", + cl::desc("Halt execution after the specified duration. " + "Set to 0s to disable (default=0s)"), + cl::init("0s"), + cl::cat(TerminationCat)); } // namespace klee namespace { @@ -314,12 +320,6 @@ cl::init(8192), cl::cat(TerminationCat)); -cl::opt<std::string> MaxInstructionTime( - "max-instruction-time", - cl::desc("Allow a single instruction to take only this much time. Enables " - "--use-forked-solver. Set to 0s to disable (default=0s)"), - cl::cat(TerminationCat)); - cl::opt<double> MaxStaticForkPct( "max-static-fork-pct", cl::init(1.), cl::desc("Maximum percentage spent by an instruction forking out of the " @@ -347,6 +347,13 @@ "instructions (default=1.0 (always))"), cl::cat(TerminationCat)); +cl::opt<std::string> TimerInterval( + "timer-interval", + cl::desc("Minimum interval to check timers. " + "Affects -max-time, -istats-write-interval, -stats-write-interval, and -uncovered-update-interval (default=1s)"), + cl::init("1s"), + cl::cat(TerminationCat)); + /*** Debugging options ***/ @@ -425,22 +432,25 @@ [ Unhandled ] = "xxx", }; + Executor::Executor(LLVMContext &ctx, const InterpreterOptions &opts, InterpreterHandler *ih) : Interpreter(opts), interpreterHandler(ih), searcher(0), externalDispatcher(new ExternalDispatcher(ctx)), statsTracker(0), - pathWriter(0), symPathWriter(0), specialFunctionHandler(0), + pathWriter(0), symPathWriter(0), specialFunctionHandler(0), timers{time::Span(TimerInterval)}, replayKTest(0), replayPath(0), usingSeeds(0), atMemoryLimit(false), inhibitForking(false), haltExecution(false), ivcEnabled(false), debugLogBuffer(debugBufferString) { - const time::Span maxCoreSolverTime(MaxCoreSolverTime); - maxInstructionTime = time::Span(MaxInstructionTime); - coreSolverTimeout = maxCoreSolverTime && maxInstructionTime ? - std::min(maxCoreSolverTime, maxInstructionTime) - : std::max(maxCoreSolverTime, maxInstructionTime); + const time::Span maxTime{MaxTime}; + if (maxTime) timers.add( + std::move(std::make_unique<Timer>(maxTime, [&]{ + klee_message("HaltTimer invoked"); + setHaltExecution(true); + }))); + coreSolverTimeout = time::Span{MaxCoreSolverTime}; if (coreSolverTimeout) UseForkedCoreSolver = true; Solver *coreSolver = klee::createCoreSolver(CoreSolverToUse); if (!coreSolver) { @@ -554,10 +564,6 @@ delete specialFunctionHandler; delete statsTracker; delete solver; - while(!timers.empty()) { - delete timers.back(); - timers.pop_back(); - } } /***/ @@ -1789,10 +1795,9 @@ // Handle possible different branch targets // We have the following assumptions: - // - each case value is mutual exclusive to all other values including the - // default value + // - each case value is mutual exclusive to all other values // - order of case branches is based on the order of the expressions of - // the scase values, still default is handled last + // the case values, still default is handled last std::vector<BasicBlock *> bbOrder; std::map<BasicBlock *, ref<Expr> > branchTargets; @@ -1816,6 +1821,10 @@ it != itE; ++it) { ref<Expr> match = EqExpr::create(cond, it->first); + // skip if case has same successor basic block as default case + // (should work even with phi nodes as a switch is a single terminating instruction) + if (it->second == si->getDefaultDest()) continue; + // Make sure that the default value does not contain this target's value defaultValue = AndExpr::create(defaultValue, Expr::createIsZero(match)); @@ -2865,9 +2874,8 @@ void Executor::run(ExecutionState &initialState) { bindModuleConstants(); - // Delay init till now so that ticks don't accrue during - // optimization and such. - initTimers(); + // Delay init till now so that ticks don't accrue during optimization and such. + timers.reset(); states.insert(&initialState); @@ -2898,7 +2906,7 @@ stepInstruction(state); executeInstruction(state, ki); - processTimers(&state, maxInstructionTime * numSeeds); + timers.invoke(); if (::dumpStates) dumpStates(); if (::dumpPTree) dumpPTree(); updateStates(&state); @@ -2954,7 +2962,7 @@ stepInstruction(state); executeInstruction(state, ki); - processTimers(&state, maxInstructionTime); + timers.invoke(); if (::dumpStates) dumpStates(); if (::dumpPTree) dumpPTree(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/lib/Core/Executor.h new/klee-2.0+20191031/lib/Core/Executor.h --- old/klee-2.0+20190920/lib/Core/Executor.h 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/lib/Core/Executor.h 2019-10-31 16:38:21.000000000 +0100 @@ -92,15 +92,6 @@ friend class MergingSearcher; public: - class Timer { - public: - Timer(); - virtual ~Timer(); - - /// The event callback. - virtual void run() = 0; - }; - typedef std::pair<ExecutionState*,ExecutionState*> StatePair; enum TerminateReason { @@ -122,8 +113,6 @@ private: static const char *TerminateReasonNames[]; - class TimerInfo; - std::unique_ptr<KModule> kmodule; InterpreterHandler *interpreterHandler; Searcher *searcher; @@ -135,7 +124,7 @@ StatsTracker *statsTracker; TreeStreamWriter *pathWriter, *symPathWriter; SpecialFunctionHandler *specialFunctionHandler; - std::vector<TimerInfo*> timers; + TimerGroup timers; std::unique_ptr<PTree> processTree; /// Keeps track of all currently ongoing merges. @@ -243,9 +232,6 @@ void executeInstruction(ExecutionState &state, KInstruction *ki); - void printFileLine(ExecutionState &state, KInstruction *ki, - llvm::raw_ostream &file); - void run(ExecutionState &initialState); // Given a concrete object in our [klee's] address space, add it to @@ -459,22 +445,10 @@ /// constant values. void bindInstructionConstants(KInstruction *KI); - void handlePointsToObj(ExecutionState &state, - KInstruction *target, - const std::vector<ref<Expr> > &arguments); - void doImpliedValueConcretization(ExecutionState &state, ref<Expr> e, ref<ConstantExpr> value); - /// Add a timer to be executed periodically. - /// - /// \param timer The timer object to run on firings. - /// \param rate The approximate delay (in seconds) between firings. - void addTimer(Timer *timer, time::Span rate); - - void initTimers(); - void processTimers(ExecutionState *current, time::Span maxInstTime); void checkMemoryUsage(); void printDebugInstructions(ExecutionState &state); void doDumpStates(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/lib/Core/ExecutorTimerInfo.h new/klee-2.0+20191031/lib/Core/ExecutorTimerInfo.h --- old/klee-2.0+20190920/lib/Core/ExecutorTimerInfo.h 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/lib/Core/ExecutorTimerInfo.h 1970-01-01 01:00:00.000000000 +0100 @@ -1,42 +0,0 @@ -//===-- ExecutorTimerInfo.h -------------------------------------*- C++ -*-===// -// -// The KLEE Symbolic Virtual Machine -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Class to wrap information for a timer. -// -//===----------------------------------------------------------------------===// - -#ifndef KLEE_EXECUTORTIMERINFO_H -#define KLEE_EXECUTORTIMERINFO_H - -#include "klee/Internal/System/Time.h" - -namespace klee { - -class Executor::TimerInfo { -public: - Timer *timer; - - /// Approximate delay per timer firing. - time::Span rate; - /// Wall time for next firing. - time::Point nextFireTime; - -public: - TimerInfo(Timer *_timer, time::Span _rate) - : timer(_timer), - rate(_rate), - nextFireTime(time::getWallTime() + rate) {} - ~TimerInfo() { delete timer; } -}; - - -} - - -#endif /* KLEE_EXECUTORTIMERINFO_H */ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/lib/Core/ExecutorTimers.cpp new/klee-2.0+20191031/lib/Core/ExecutorTimers.cpp --- old/klee-2.0+20190920/lib/Core/ExecutorTimers.cpp 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/lib/Core/ExecutorTimers.cpp 2019-10-31 16:38:21.000000000 +0100 @@ -1,141 +0,0 @@ -//===-- ExecutorTimers.cpp ------------------------------------------------===// -// -// The KLEE Symbolic Virtual Machine -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// - -#include "CoreStats.h" -#include "Executor.h" -#include "ExecutorTimerInfo.h" -#include "PTree.h" -#include "StatsTracker.h" - -#include "klee/ExecutionState.h" -#include "klee/Internal/Module/InstructionInfoTable.h" -#include "klee/Internal/Module/KInstruction.h" -#include "klee/Internal/Module/KModule.h" -#include "klee/Internal/Support/ErrorHandling.h" -#include "klee/Internal/System/Time.h" -#include "klee/OptionCategories.h" - -#include "llvm/IR/Function.h" -#include "llvm/Support/CommandLine.h" - -#include <math.h> -#include <signal.h> -#include <string> -#include <sys/time.h> -#include <unistd.h> - -using namespace llvm; -using namespace klee; - -namespace klee { -cl::opt<std::string> - MaxTime("max-time", - cl::desc("Halt execution after the specified number of seconds. " - "Set to 0s to disable (default=0s)"), - cl::init("0s"), - cl::cat(TerminationCat)); -} - -/// - -class HaltTimer : public Executor::Timer { - Executor *executor; - -public: - HaltTimer(Executor *_executor) : executor(_executor) {} - ~HaltTimer() {} - - void run() { - klee_message("HaltTimer invoked"); - executor->setHaltExecution(true); - } -}; - -/// - -static const time::Span kMilliSecondsPerTick(time::milliseconds(100)); -static volatile unsigned timerTicks = 0; - -static void onAlarm(int) { - ++timerTicks; -} - -// oooogalay -static void setupHandler() { - itimerval t{}; - timeval tv = static_cast<timeval>(kMilliSecondsPerTick); - t.it_interval = t.it_value = tv; - - ::setitimer(ITIMER_REAL, &t, nullptr); - ::signal(SIGALRM, onAlarm); -} - -void Executor::initTimers() { - static bool first = true; - - if (first) { - first = false; - setupHandler(); - } - - const time::Span maxTime(MaxTime); - if (maxTime) { - addTimer(new HaltTimer(this), maxTime); - } -} - -/// - -Executor::Timer::Timer() {} - -Executor::Timer::~Timer() {} - -void Executor::addTimer(Timer *timer, time::Span rate) { - timers.push_back(new TimerInfo(timer, rate)); -} - -void Executor::processTimers(ExecutionState *current, - time::Span maxInstTime) { - static unsigned callsWithoutCheck = 0; - unsigned ticks = timerTicks; - - if (!ticks && ++callsWithoutCheck > 1000) { - setupHandler(); - ticks = 1; - } - - if (ticks) { - if (maxInstTime && current && - std::find(removedStates.begin(), removedStates.end(), current) == - removedStates.end()) { - if (timerTicks * kMilliSecondsPerTick > maxInstTime) { - klee_warning("max-instruction-time exceeded: %.2fs", (timerTicks * kMilliSecondsPerTick).toSeconds()); - terminateStateEarly(*current, "max-instruction-time exceeded"); - } - } - - if (!timers.empty()) { - auto time = time::getWallTime(); - - for (std::vector<TimerInfo*>::iterator it = timers.begin(), - ie = timers.end(); it != ie; ++it) { - TimerInfo *ti = *it; - - if (time >= ti->nextFireTime) { - ti->timer->run(); - ti->nextFireTime = time + ti->rate; - } - } - } - - timerTicks = 0; - callsWithoutCheck = 0; - } -} - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/lib/Core/StatsTracker.cpp new/klee-2.0+20191031/lib/Core/StatsTracker.cpp --- old/klee-2.0+20190920/lib/Core/StatsTracker.cpp 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/lib/Core/StatsTracker.cpp 2019-10-31 16:38:21.000000000 +0100 @@ -122,40 +122,6 @@ return OutputIStats; } -namespace klee { - class WriteIStatsTimer : public Executor::Timer { - StatsTracker *statsTracker; - - public: - WriteIStatsTimer(StatsTracker *_statsTracker) : statsTracker(_statsTracker) {} - ~WriteIStatsTimer() {} - - void run() { statsTracker->writeIStats(); } - }; - - class WriteStatsTimer : public Executor::Timer { - StatsTracker *statsTracker; - - public: - WriteStatsTimer(StatsTracker *_statsTracker) : statsTracker(_statsTracker) {} - ~WriteStatsTimer() {} - - void run() { statsTracker->writeStatsLine(); } - }; - - class UpdateReachableTimer : public Executor::Timer { - StatsTracker *statsTracker; - - public: - UpdateReachableTimer(StatsTracker *_statsTracker) : statsTracker(_statsTracker) {} - - void run() { statsTracker->computeReachableUncovered(); } - }; - -} - -// - /// Check for special cases where we statically know an instruction is /// uncoverable. Currently the case is an unreachable instruction /// following a noreturn call; the instruction is really only there to @@ -297,20 +263,26 @@ writeStatsLine(); if (statsWriteInterval) - executor.addTimer(new WriteStatsTimer(this), statsWriteInterval); + executor.timers.add(std::move(std::make_unique<Timer>(statsWriteInterval, [&]{ + writeStatsLine(); + }))); } // Add timer to calculate uncovered instructions if needed by the solver if (updateMinDistToUncovered) { computeReachableUncovered(); - executor.addTimer(new UpdateReachableTimer(this), time::Span(UncoveredUpdateInterval)); + executor.timers.add(std::move(std::make_unique<Timer>(time::Span{UncoveredUpdateInterval}, [&]{ + computeReachableUncovered(); + }))); } if (OutputIStats) { istatsFile = executor.interpreterHandler->openOutputFile("run.istats"); if (istatsFile) { if (iStatsWriteInterval) - executor.addTimer(new WriteIStatsTimer(this), iStatsWriteInterval); + executor.timers.add(std::move(std::make_unique<Timer>(iStatsWriteInterval, [&]{ + writeIStats(); + }))); } else { klee_error("Unable to open instruction level stats file (run.istats)."); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/lib/Core/TimingSolver.cpp new/klee-2.0+20191031/lib/Core/TimingSolver.cpp --- old/klee-2.0+20190920/lib/Core/TimingSolver.cpp 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/lib/Core/TimingSolver.cpp 2019-10-31 16:38:21.000000000 +0100 @@ -37,7 +37,7 @@ bool success = solver->evaluate(Query(state.constraints, expr), result); - state.queryCost += timer.check(); + state.queryCost += timer.delta(); return success; } @@ -57,7 +57,7 @@ bool success = solver->mustBeTrue(Query(state.constraints, expr), result); - state.queryCost += timer.check(); + state.queryCost += timer.delta(); return success; } @@ -100,7 +100,7 @@ bool success = solver->getValue(Query(state.constraints, expr), result); - state.queryCost += timer.check(); + state.queryCost += timer.delta(); return success; } @@ -120,7 +120,7 @@ ConstantExpr::alloc(0, Expr::Bool)), objects, result); - state.queryCost += timer.check(); + state.queryCost += timer.delta(); return success; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/lib/Module/Checks.cpp new/klee-2.0+20191031/lib/Module/Checks.cpp --- old/klee-2.0+20190920/lib/Module/Checks.cpp 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/lib/Module/Checks.cpp 2019-10-31 16:38:21.000000000 +0100 @@ -71,9 +71,9 @@ LLVMContext &ctx = M.getContext(); KleeIRMetaData md(ctx); - auto divZeroCheckFunction = cast<Function>( + auto divZeroCheckFunction = M.getOrInsertFunction("klee_div_zero_check", Type::getVoidTy(ctx), - Type::getInt64Ty(ctx) KLEE_LLVM_GOIF_TERMINATOR)); + Type::getInt64Ty(ctx) KLEE_LLVM_GOIF_TERMINATOR); for (auto &divInst : divInstruction) { llvm::IRBuilder<> Builder(divInst /* Inserts before divInst*/); @@ -130,9 +130,9 @@ // Retrieve the checker function auto &ctx = M.getContext(); KleeIRMetaData md(ctx); - auto overshiftCheckFunction = cast<Function>(M.getOrInsertFunction( + auto overshiftCheckFunction = M.getOrInsertFunction( "klee_overshift_check", Type::getVoidTy(ctx), Type::getInt64Ty(ctx), - Type::getInt64Ty(ctx) KLEE_LLVM_GOIF_TERMINATOR)); + Type::getInt64Ty(ctx) KLEE_LLVM_GOIF_TERMINATOR); for (auto &shiftInst : shiftInstructions) { llvm::IRBuilder<> Builder(shiftInst); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/lib/Module/IntrinsicCleaner.cpp new/klee-2.0+20191031/lib/Module/IntrinsicCleaner.cpp --- old/klee-2.0+20190920/lib/Module/IntrinsicCleaner.cpp 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/lib/Module/IntrinsicCleaner.cpp 2019-10-31 16:38:21.000000000 +0100 @@ -264,14 +264,19 @@ case Intrinsic::trap: { // Intrinsic instruction "llvm.trap" found. Directly lower it to // a call of the abort() function. - Function *F = cast<Function>( - M.getOrInsertFunction("abort", Type::getVoidTy(ctx) - KLEE_LLVM_GOIF_TERMINATOR)); - F->setDoesNotReturn(); - F->setDoesNotThrow(); + auto C = M.getOrInsertFunction("abort", Type::getVoidTy(ctx) + KLEE_LLVM_GOIF_TERMINATOR); +#if LLVM_VERSION_CODE >= LLVM_VERSION(9, 0) + if (auto *F = dyn_cast<Function>(C.getCallee())) { +#else + if (auto *F = dyn_cast<Function>(C)) { +#endif + F->setDoesNotReturn(); + F->setDoesNotThrow(); + } llvm::IRBuilder<> Builder(ii); - Builder.CreateCall(F); + Builder.CreateCall(C); Builder.CreateUnreachable(); i = ii->eraseFromParent(); @@ -291,7 +296,9 @@ case Intrinsic::objectsize: { // We don't know the size of an object in general so we replace // with 0 or -1 depending on the second argument to the intrinsic. -#if LLVM_VERSION_CODE >= LLVM_VERSION(5, 0) +#if LLVM_VERSION_CODE >= LLVM_VERSION(9, 0) + assert(ii->getNumArgOperands() == 4 && "wrong number of arguments"); +#elif LLVM_VERSION_CODE >= LLVM_VERSION(5, 0) assert(ii->getNumArgOperands() == 3 && "wrong number of arguments"); #else assert(ii->getNumArgOperands() == 2 && "wrong number of arguments"); @@ -306,12 +313,22 @@ #if LLVM_VERSION_CODE >= LLVM_VERSION(5, 0) auto nullArg = ii->getArgOperand(2); - assert(nullArg && "Failed to get second argument"); + assert(nullArg && "Failed to get third argument"); auto nullArgAsInt = dyn_cast<ConstantInt>(nullArg); assert(nullArgAsInt && "Third arg is not a ConstantInt"); assert(nullArgAsInt->getBitWidth() == 1 && "Third argument is not an i1"); - /* TODO should we do something with the 3rd argument? */ + // TODO: should we do something with the 3rd argument? +#endif + +#if LLVM_VERSION_CODE >= LLVM_VERSION(9, 0) + auto dynamicArg = ii->getArgOperand(3); + assert(dynamicArg && "Failed to get fourth argument"); + auto dynamicArgAsInt = dyn_cast<ConstantInt>(dynamicArg); + assert(dynamicArgAsInt && "Fourth arg is not a ConstantInt"); + assert(dynamicArgAsInt->getBitWidth() == 1 && + "Fourth argument is not an i1"); + // TODO: should we do something with the 4th argument? #endif Value *replacement = NULL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/lib/Module/KModule.cpp new/klee-2.0+20191031/lib/Module/KModule.cpp --- old/klee-2.0+20190920/lib/Module/KModule.cpp 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/lib/Module/KModule.cpp 2019-10-31 16:38:21.000000000 +0100 @@ -140,10 +140,15 @@ if (arr) { for (unsigned i=0; i<arr->getNumOperands(); i++) { auto cs = cast<ConstantStruct>(arr->getOperand(i)); - // There is a third *optional* element in global_ctor elements (``i8 - // @data``). + // There is a third element in global_ctor elements (``i8 @data``). +#if LLVM_VERSION_CODE >= LLVM_VERSION(9, 0) + assert(cs->getNumOperands() == 3 && + "unexpected element in ctor initializer list"); +#else + // before LLVM 9.0, the third operand was optional assert((cs->getNumOperands() == 2 || cs->getNumOperands() == 3) && "unexpected element in ctor initializer list"); +#endif auto fp = cs->getOperand(1); if (!fp->isNullValue()) { if (auto ce = dyn_cast<llvm::ConstantExpr>(fp)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/lib/Solver/SolverCmdLine.cpp new/klee-2.0+20191031/lib/Solver/SolverCmdLine.cpp --- old/klee-2.0+20190920/lib/Solver/SolverCmdLine.cpp 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/lib/Solver/SolverCmdLine.cpp 2019-10-31 16:38:21.000000000 +0100 @@ -118,18 +118,15 @@ StringMap<cl::Option *> &map = cl::getRegisteredOptions(); for (auto &elem : map) { - if (elem.second->Category == &Category) { - elem.second->setHiddenFlag(cl::Hidden); - } - } -} - -void KCommandLine::HideUnrelatedOptions(cl::OptionCategory &Category) { - StringMap<cl::Option *> &map = cl::getRegisteredOptions(); - for (StringMap<cl::Option *>::iterator i = map.begin(), e = map.end(); i != e; - i++) { - if (i->second->Category != &Category) { - i->second->setHiddenFlag(cl::Hidden); +#if LLVM_VERSION_CODE >= LLVM_VERSION(9, 0) + for (auto &cat : elem.second->Categories) { +#else + { + auto &cat = elem.second->Category; +#endif + if (cat == &Category) { + elem.second->setHiddenFlag(cl::Hidden); + } } } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/lib/Support/Timer.cpp new/klee-2.0+20191031/lib/Support/Timer.cpp --- old/klee-2.0+20190920/lib/Support/Timer.cpp 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/lib/Support/Timer.cpp 2019-10-31 16:38:21.000000000 +0100 @@ -7,16 +7,75 @@ // //===----------------------------------------------------------------------===// -#include "klee/Config/Version.h" +#include "klee/Internal/Support/ErrorHandling.h" #include "klee/Internal/Support/Timer.h" #include "klee/Internal/System/Time.h" + using namespace klee; -WallTimer::WallTimer() { - start = time::getWallTime(); + +// WallTimer + +WallTimer::WallTimer() : start{time::getWallTime()} {} + +time::Span WallTimer::delta() const { + return {time::getWallTime() - start}; +} + + +// Timer + +Timer::Timer(const time::Span &interval, std::function<void()> &&callback) : + interval{interval}, nextInvocationTime{time::getWallTime() + interval}, run{std::move(callback)} {}; + +time::Span Timer::getInterval() const { + return interval; +}; + +void Timer::invoke(const time::Point ¤tTime) { + if (currentTime < nextInvocationTime) return; + + run(); + nextInvocationTime = currentTime + interval; +}; + +void Timer::reset(const time::Point ¤tTime) { + nextInvocationTime = currentTime + interval; +}; + + +// TimerGroup + +TimerGroup::TimerGroup(const time::Span &minInterval) : + invocationTimer{ + minInterval, + [&]{ + // invoke timers + for (auto &timer : timers) + timer->invoke(currentTime); + } + } {}; + +void TimerGroup::add(std::unique_ptr<klee::Timer> timer) { + const auto &interval = timer->getInterval(); + const auto &minInterval = invocationTimer.getInterval(); + if (interval < minInterval) + klee_warning("Timer interval below minimum timer interval (-timer-interval)"); + if (interval.toMicroseconds() % minInterval.toMicroseconds()) + klee_warning("Timer interval not a multiple of timer interval (-timer-interval)"); + + timers.emplace_back(std::move(timer)); +} + +void TimerGroup::invoke() { + currentTime = time::getWallTime(); + invocationTimer.invoke(currentTime); } -time::Span WallTimer::check() { - return time::Span(time::getWallTime() - start); +void TimerGroup::reset() { + currentTime = time::getWallTime(); + invocationTimer.reset(currentTime); + for (auto &timer : timers) + timer->reset(currentTime); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/runtime/klee-libc/bcmp.c new/klee-2.0+20191031/runtime/klee-libc/bcmp.c --- old/klee-2.0+20190920/runtime/klee-libc/bcmp.c 1970-01-01 01:00:00.000000000 +0100 +++ new/klee-2.0+20191031/runtime/klee-libc/bcmp.c 2019-10-31 16:38:21.000000000 +0100 @@ -0,0 +1,19 @@ +/*===-- bcmp.c ------------------------------------------------------------===// +// +// The KLEE Symbolic Virtual Machine +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===*/ + +#include <strings.h> + +int bcmp(const void *s1, const void *s2, size_t n) { + const unsigned char *p1 = s1, *p2 = s2; + while (--n != 0) { + if (*p1++ != *p2++) + return 1; + } + return 0; +} diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/scripts/build/d-klee-linux-ubuntu.inc new/klee-2.0+20191031/scripts/build/d-klee-linux-ubuntu.inc --- old/klee-2.0+20190920/scripts/build/d-klee-linux-ubuntu.inc 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/scripts/build/d-klee-linux-ubuntu.inc 2019-10-31 16:38:21.000000000 +0100 @@ -1,7 +1,7 @@ # TODO remove adding sudo package # Create ``klee`` user for container with password ``klee``. # and give it password-less sudo access (temporarily so we can use the TravisCI scripts) -RUN apt update && apt -y --no-install-recommends install sudo && \ +RUN apt update && apt -y --no-install-recommends install sudo file && \ rm -rf /var/lib/apt/lists/* && \ useradd -m klee && \ echo klee:klee | chpasswd && \ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/scripts/build/run-tests.sh new/klee-2.0+20191031/scripts/build/run-tests.sh --- old/klee-2.0+20190920/scripts/build/run-tests.sh 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/scripts/build/run-tests.sh 2019-10-31 16:38:21.000000000 +0100 @@ -70,7 +70,7 @@ for backend in $available_metasmt_backends; do if [ "X${METASMT_DEFAULT}" != "X$backend" ]; then if [ "$backend" == "cvc4" ]; then - for num in {1..5}; do sleep 120; echo 'Keep Travis alive'; done & + for num in {1..10}; do sleep 120; echo 'Keep Travis alive'; done & fi lit -v --param klee_opts=-metasmt-backend="$backend" --param kleaver_opts=-metasmt-backend="$backend" test/ fi diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/test/Expr/Evaluate2.kquery new/klee-2.0+20191031/test/Expr/Evaluate2.kquery --- old/klee-2.0+20190920/test/Expr/Evaluate2.kquery 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/test/Expr/Evaluate2.kquery 2019-10-31 16:38:21.000000000 +0100 @@ -2,4 +2,5 @@ # RUN: grep "Query 0: VALID" %t.log # XFAIL: * +# see https://github.com/klee/klee/issues/97 (query [false] false) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/test/Feature/SolverTimeout.c new/klee-2.0+20191031/test/Feature/SolverTimeout.c --- old/klee-2.0+20190920/test/Feature/SolverTimeout.c 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/test/Feature/SolverTimeout.c 2019-10-31 16:38:21.000000000 +0100 @@ -1,9 +1,9 @@ -// RUN: %clang %s -emit-llvm %O0opt -c -o %t1.bc +// RUN: %clang %s -emit-llvm %O0opt -c -o %t.bc // RUN: rm -rf %t.klee-out -// RUN: %klee --output-dir=%t.klee-out --max-solver-time=1 %t1.bc -// FIXME: This test occasionally fails when using Z3 4.4.1 but -// not when using Z3 from the master branch. So disable the test for now. -// REQUIRES: stp +// RUN: %klee --output-dir=%t.klee-out --max-solver-time=1 %t.bc +// +// Note: This test occasionally fails when using Z3 4.4.1 + #include <stdio.h> int main() { diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/test/Intrinsics/objectsize.leq80.ll new/klee-2.0+20191031/test/Intrinsics/objectsize.leq80.ll --- old/klee-2.0+20190920/test/Intrinsics/objectsize.leq80.ll 1970-01-01 01:00:00.000000000 +0100 +++ new/klee-2.0+20191031/test/Intrinsics/objectsize.leq80.ll 2019-10-31 16:38:21.000000000 +0100 @@ -0,0 +1,35 @@ +; REQUIRES: lt-llvm-9.0 +; LLVM 5 added parameter "nullunknown" to @llvm.objectsize +; REQUIRES: geq-llvm-5.0 +; RUN: %llvmas %s -o=%t.bc +; RUN: rm -rf %t.klee-out +; RUN: %klee -exit-on-error --output-dir=%t.klee-out --optimize=false %t.bc +; ModuleID = 'objectsize.c' +target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define i32 @main() nounwind uwtable { +entry: + %a = alloca i8*, align 8 + %0 = load i8*, i8** %a, align 8 + %1 = call i64 @llvm.objectsize.i64.p0i8(i8* %0, i1 true, i1 false) + %cmp = icmp ne i64 %1, 0 + br i1 %cmp, label %abort.block, label %continue.block + +continue.block: + %2 = load i8*, i8** %a, align 8 + %3 = call i64 @llvm.objectsize.i64.p0i8(i8* %2, i1 false, i1 false) + %cmp1 = icmp ne i64 %3, -1 + br i1 %cmp1, label %abort.block, label %exit.block + +exit.block: + ret i32 0 + +abort.block: + call void @abort() + unreachable +} + +declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1) nounwind readnone + +declare void @abort() noreturn nounwind diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/test/Intrinsics/objectsize.ll new/klee-2.0+20191031/test/Intrinsics/objectsize.ll --- old/klee-2.0+20190920/test/Intrinsics/objectsize.ll 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/test/Intrinsics/objectsize.ll 2019-10-31 16:38:21.000000000 +0100 @@ -1,5 +1,5 @@ -; LLVM 5 added nullunknown parameter to @llvm.objectsize -; REQUIRES: geq-llvm-5.0 +; LLVM 9 added parameter "dynamic" to @llvm.objectsize +; REQUIRES: geq-llvm-9.0 ; RUN: %llvmas %s -o=%t.bc ; RUN: rm -rf %t.klee-out ; RUN: %klee -exit-on-error --output-dir=%t.klee-out --optimize=false %t.bc @@ -11,13 +11,13 @@ entry: %a = alloca i8*, align 8 %0 = load i8*, i8** %a, align 8 - %1 = call i64 @llvm.objectsize.i64.p0i8(i8* %0, i1 true, i1 false) + %1 = call i64 @llvm.objectsize.i64.p0i8(i8* %0, i1 true, i1 false, i1 false) %cmp = icmp ne i64 %1, 0 br i1 %cmp, label %abort.block, label %continue.block continue.block: %2 = load i8*, i8** %a, align 8 - %3 = call i64 @llvm.objectsize.i64.p0i8(i8* %2, i1 false, i1 false) + %3 = call i64 @llvm.objectsize.i64.p0i8(i8* %2, i1 false, i1 false, i1 false) %cmp1 = icmp ne i64 %3, -1 br i1 %cmp1, label %abort.block, label %exit.block @@ -29,6 +29,6 @@ unreachable } -declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1) nounwind readnone +declare i64 @llvm.objectsize.i64.p0i8(i8*, i1, i1, i1) nounwind readnone declare void @abort() noreturn nounwind diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/test/Runtime/FreeStanding/freestanding_only.c new/klee-2.0+20191031/test/Runtime/FreeStanding/freestanding_only.c --- old/klee-2.0+20190920/test/Runtime/FreeStanding/freestanding_only.c 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/test/Runtime/FreeStanding/freestanding_only.c 2019-10-31 16:38:21.000000000 +0100 @@ -26,6 +26,7 @@ assert(memcmp(src, dst, LENGTH) == 0); // CHECK-NOT: calling external: memcmp + // CHECK-NOT: calling external: bcmp assert(*src == 42); assert(*src == *dst); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/test/lit.cfg new/klee-2.0+20191031/test/lit.cfg --- old/klee-2.0+20190920/test/lit.cfg 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/test/lit.cfg 2019-10-31 16:38:21.000000000 +0100 @@ -39,12 +39,12 @@ if klee_obj_root is not None: klee_tools_dir = getattr(config, 'klee_tools_dir', None) if not klee_tools_dir: - lit.fatal('No KLEE tools dir set!') + lit_config.fatal('No KLEE tools dir set!') # Check LLVM tool directory llvm_tools_dir = getattr(config, 'llvm_tools_dir', None) if not llvm_tools_dir: - lit.fatal('No LLVM tool directory set!') + lit_config.fatal('No LLVM tool directory set!') path = os.path.pathsep.join( ( @@ -80,7 +80,7 @@ # Check that the object root is known. if config.test_exec_root is None: - lit.fatal('test execution root not set!') + lit_config.fatal('test execution root not set!') # Add substitutions from lit.site.cfg @@ -88,7 +88,7 @@ for name in subs: value = getattr(config, name, None) if value == None: - lit.fatal('{0} is not set'.format(name)) + lit_config.fatal('{0} is not set'.format(name)) config.substitutions.append( ('%' + name, value)) # Add a substitution for lli. @@ -114,14 +114,8 @@ # Get KLEE and Kleaver specific parameters passed on llvm-lit cmd line # e.g. llvm-lit --param klee_opts=--help -try: - lit.params -except AttributeError: - klee_extra_params = lit_config.params.get('klee_opts',"") - kleaver_extra_params = lit_config.params.get('kleaver_opts',"") -else: - klee_extra_params = lit.params.get('klee_opts',"") - kleaver_extra_params = lit.params.get('kleaver_opts',"") +klee_extra_params = lit_config.params.get('klee_opts',"") +kleaver_extra_params = lit_config.params.get('kleaver_opts',"") if len(klee_extra_params) != 0: print("Passing extra KLEE command line args: {0}".format( @@ -161,9 +155,14 @@ # Add feature for the LLVM version in use, so it can be tested in REQUIRES and # XFAIL checks. We also add "not-XXX" variants, for the same reason. -known_llvm_versions = set(["3.8", "3.9", "4.0", "5.0", "6.0", "7.0", "8.0"]) +known_llvm_versions = set(["3.8", "3.9", "4.0", "5.0", "6.0", "7.0", "7.1", "8.0", "9.0"]) current_llvm_version = "%s.%s" % (config.llvm_version_major, config.llvm_version_minor) + +if current_llvm_version not in known_llvm_versions: + lit_config.fatal("LLVM Version %s is not listed in known_llvm_versions!" + % current_llvm_version) + config.available_features.add("llvm-" + current_llvm_version) for version in known_llvm_versions: if version != current_llvm_version: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/test/regression/2014-09-13-debug-info.c new/klee-2.0+20191031/test/regression/2014-09-13-debug-info.c --- old/klee-2.0+20190920/test/regression/2014-09-13-debug-info.c 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/test/regression/2014-09-13-debug-info.c 2019-10-31 16:38:21.000000000 +0100 @@ -8,13 +8,13 @@ // one with the prefered CEX. We verify this by using ktest-tool to dump the // values, and then checking the output. // -// RUN: /bin/sh -c "ktest-tool %t.klee-out/*.ktest" | sort > %t.data-values +// RUN: /bin/sh -c "ktest-tool %t.klee-out/*.ktest" > %t.data-values // RUN: FileCheck < %t.data-values %s -// CHECK: object 0: int : 0 -// CHECK: object 0: int : 17 -// CHECK: object 0: int : 32 -// CHECK: object 0: int : 99 +// CHECK-DAG: object 0: int : 0 +// CHECK-DAG: object 0: int : 17 +// CHECK-DAG: object 0: int : 32 +// CHECK-DAG: object 0: int : 99 #include "klee/klee.h" @@ -24,7 +24,9 @@ void f3(void) {} int main() { - int x = klee_range(0, 256, "x"); + int x; + klee_make_symbolic(&x, sizeof x, "x"); + klee_assume((unsigned) x < 256); if (x == 17) { f0(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/test/regression/2019-08-02-missing-switch-default.ll new/klee-2.0+20191031/test/regression/2019-08-02-missing-switch-default.ll --- old/klee-2.0+20190920/test/regression/2019-08-02-missing-switch-default.ll 1970-01-01 01:00:00.000000000 +0100 +++ new/klee-2.0+20191031/test/regression/2019-08-02-missing-switch-default.ll 2019-10-31 16:38:21.000000000 +0100 @@ -0,0 +1,50 @@ +; REQUIRES: geq-llvm-3.8 +; RUN: rm -rf %t.klee-out +; RUN: llvm-as -f %s -o %t.bc +; RUN: %klee --switch-type=internal --output-dir=%t.klee-out %t.bc +; RUN: FileCheck --input-file=%t.klee-out/info %s +; CHECK: KLEE: done: completed paths = 3 + +target triple = "x86_64-pc-linux-gnu" + [email protected] = private unnamed_addr constant [5 x i8] c"cond\00", align 1 + +define i32 @main() #0 { + %1 = alloca i32, align 4 + %2 = alloca i32, align 4 + %3 = alloca i32, align 4 + store i32 0, i32* %1, align 4 + %4 = bitcast i32* %2 to i8* + call void @klee_make_symbolic(i8* %4, i64 4, i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str, i32 0, i32 0)) + store i32 0, i32* %3, align 4 + %5 = load i32, i32* %2, align 4 + switch i32 %5, label %7 [ + i32 1, label %6 + i32 5, label %7 + ] + +; <label>:6: + store i32 1, i32* %3, align 4 + br label %8 + +; <label>:7: + store i32 5, i32* %3, align 4 + br label %8 + +; <label>:8: + %9 = load i32, i32* %2, align 4 + %10 = icmp eq i32 %9, 7 + br i1 %10, label %11, label %12 + +; <label>:11: + store i32 7, i32* %3, align 4 + br label %12 + +; <label>:12: + %13 = load i32, i32* %1, align 4 + ret i32 %13 +} + +declare void @klee_make_symbolic(i8*, i64, i8*) + +attributes #0 = { noinline nounwind optnone uwtable } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/tools/klee/main.cpp new/klee-2.0+20191031/tools/klee/main.cpp --- old/klee-2.0+20190920/tools/klee/main.cpp 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/tools/klee/main.cpp 2019-10-31 16:38:21.000000000 +0100 @@ -715,9 +715,10 @@ // link against a libc implementation. Preparing for libc linking (i.e. // linking with uClibc will expect a main function and rename it to // _user_main. We just provide the definition here. - if (!libCPrefix.empty()) - mainFn->getParent()->getOrInsertFunction(EntryPoint, - mainFn->getFunctionType()); + if (!libCPrefix.empty() && !mainFn->getParent()->getFunction(EntryPoint)) + llvm::Function::Create(mainFn->getFunctionType(), + llvm::Function::ExternalLinkage, EntryPoint, + mainFn->getParent()); llvm::Function *wrapper = nullptr; for (auto &module : loadedModules) { @@ -1067,7 +1068,7 @@ if (!libcMainFn) klee_error("Could not add %s wrapper", libcMainFunction.str().c_str()); - auto inModuleRefernce = libcMainFn->getParent()->getOrInsertFunction( + auto inModuleReference = libcMainFn->getParent()->getOrInsertFunction( userMainFn->getName(), userMainFn->getFunctionType()); const auto ft = libcMainFn->getFunctionType(); @@ -1088,8 +1089,13 @@ llvm::IRBuilder<> Builder(bb); std::vector<llvm::Value*> args; - args.push_back( - llvm::ConstantExpr::getBitCast(inModuleRefernce, ft->getParamType(0))); + args.push_back(llvm::ConstantExpr::getBitCast( +#if LLVM_VERSION_CODE >= LLVM_VERSION(9, 0) + cast<llvm::Constant>(inModuleReference.getCallee()), +#else + inModuleReference, +#endif + ft->getParamType(0))); args.push_back(&*(stub->arg_begin())); // argc auto arg_it = stub->arg_begin(); args.push_back(&*(++arg_it)); // argv diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/klee-2.0+20190920/tools/klee-replay/klee-replay.c new/klee-2.0+20191031/tools/klee-replay/klee-replay.c --- old/klee-2.0+20190920/tools/klee-replay/klee-replay.c 2019-09-20 16:45:39.000000000 +0200 +++ new/klee-2.0+20191031/tools/klee-replay/klee-replay.c 2019-10-31 16:38:21.000000000 +0100 @@ -321,10 +321,17 @@ } } + // Executable needs to be converted to an absolute path, as klee-replay calls + // chdir just before executing it + char executable[PATH_MAX]; + if (!realpath(argv[optind], executable)) { + snprintf(executable, PATH_MAX, "KLEE-REPLAY: ERROR: executable %s:", + argv[optind]); + perror(executable); + exit(1); + } /* Normal execution path ... */ - char* executable = argv[optind]; - /* make sure this process has the CAP_SYS_CHROOT capability, if possible. */ #ifdef HAVE_SYS_CAPABILITY_H if (rootdir) @@ -337,14 +344,6 @@ exit(1); } - /* Verify the executable exists. */ - FILE *f = fopen(executable, "r"); - if (!f) { - fprintf(stderr, "KLEE-REPLAY: ERROR: executable %s not found.\n", executable); - exit(1); - } - fclose(f); - int idx = 0; for (idx = optind + 1; idx != argc; ++idx) { char* input_fname = argv[idx]; ++++++ not.cpp ++++++ --- /var/tmp/diff_new_pack.k5bjxt/_old 2019-11-04 17:16:05.164881592 +0100 +++ /var/tmp/diff_new_pack.k5bjxt/_new 2019-11-04 17:16:05.164881592 +0100 @@ -1,9 +1,8 @@ //===- not.cpp - The 'not' testing tool -----------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // Usage:
