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 - jslaby@suse.com
+
+- 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::optstd::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 run;
+ public:
+ /// \param interval The time span between callback invocations.
+ /// \param callback The event callback.
+ Timer(const time::Span &interval, std::function &&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 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::optstd::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::optstd::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::optstd::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 bbOrder;
std::map 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 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 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[ &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
-#include
-#include <string>
-#include
-#include
-
-using namespace llvm;
-using namespace klee;
-
-namespace klee {
-cl::optstd::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::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_castllvm::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 &map = cl::getRegisteredOptions();
for (auto &elem : map) {
- if (elem.second->Category == &Category) {
- elem.second->setHiddenFlag(cl::Hidden);
- }
- }
-}
-
-void KCommandLine::HideUnrelatedOptions(cl::OptionCategory &Category) {
- StringMap &map = cl::getRegisteredOptions();
- for (StringMap::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 &&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_ptrklee::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
+
+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
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"
+
+@.str = 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::vectorllvm::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)
+ castllvm::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:]