Hello community, here is the log from the commit of package klee for openSUSE:Factory checked in at 2018-12-04 20:57:20 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/klee (Old) and /work/SRC/openSUSE:Factory/.klee.new.19453 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "klee" Tue Dec 4 20:57:20 2018 rev:13 rq:653715 version:1.4.0+20181026 Changes: -------- --- /work/SRC/openSUSE:Factory/klee/klee.changes 2018-09-24 13:13:11.965713357 +0200 +++ /work/SRC/openSUSE:Factory/.klee.new.19453/klee.changes 2018-12-04 20:57:23.508649020 +0100 @@ -1,0 +2,90 @@ +Mon Oct 29 16:28:27 UTC 2018 - Jiri Slaby <jsl...@suse.com> + +- switch to LLVM 7 +- add disable-failing-test.patch + +------------------------------------------------------------------- +Sat Oct 27 07:24:23 UTC 2018 - opensuse-packag...@opensuse.org + +- Update to version 1.4.0+20181026: + * travis: enable LLVM 7 testing + * llvm7: handle new header files + * llvm7: adapt to new openFileForWrite + * llvm7: WriteBitcodeToFile takes Module & + * Added gen-bout tool to generate ktest file (file.bout) using specified concrete arguments and files. + * travis: enable LLVM 6 testing + * llvm6: handle headers renaming + * llvm6: SetVersionPrinter now passes down a stream + * travis: enable LLVM 5 testing + * llvm5: APInt->getSignBit -> getSignMask + * llvm5: CallSite.paramHasAttr is indexed from 0 + * llvm5: test, add -disable-O0-optnone to -O0 + * llvm5: test, change objectsize + * llvm5: Intrinsic::objectsize has three arguments + * llvm5: use MutableArrayRef for APFloat::convertToInteger + * llvm5: handle new file_magic's location + * llvm5: SwitchInst case functions now return pointers + * llvm5: handle getOrInsertFunction terminator + * llvm5: integerPartWidth is from llvm::APFloatBase + * llvm5: avoid ++ on function->arg_begin() + * Add testcase for shift check + * ShiftChecker: Instrument shift instructions only once + * ShiftChecker: Avoid unneeded checks + * ShiftCheck: Use llvm::Builder instead of Inst::Create* + * Add test case for div checker + * DivCheck do not instrument multiple times + * DivCheck Skip unneeded checks + * Use llvm::Builder for DivCheck instrumentation + * Introduce KLEEIRMetaData to manipulate LLVM-IR metadata + * Added lowering pass + * refactor klee_open_output_file to return std::unique_ptr + * use klee_open_output_file for uncompressed logs + * Updated an include to reflect a recent filename change + * Move unrelated function from ReadExpr class + * Avoid unsafe static downcasts + * Modernize code + * Move optimization specific headers away from the project include directory + * Clean-up headers + * Use std::unordered collections as we use C++11 + * Remove unneeded externs + * Remove condition check before function invocation + * Move ConstantExpr check inside optimizeExpr function + * optimizeExpr: return the result as return value instead as function argument + * Make valueOnly parameter of optimizeExpr explicit + * Fixed compilation of array optimization patch with LLVM >= 4.0 + * Added missing headers and clang-format the files + * Added support for KLEE value-based array optimization + * Added support for KLEE index-based array optimization + * tests: disable CompressedExprLogging on zlib-less systems + * Small changes to comments + * Added missing header to SolverCmdLine.h and clang-format it + * Renamed klee/CommandLine.h to klee/SolverCmdLine.h, since this file is meant to have only solver options. + * fix handling of failing external calls + * cmake/lit: add asan/non-asan, ubsan/non-ubsan flags + * cleanup headers, whitespaces, and types + * add support for klee-replay on OSX + * Workaround for flaky coverage + * kleeModule: always link irreader (required since llvm 3.3) + * remove obsolete dependency of kleeModule on kleeCore + * config.h.cmin: remove obsolete cmakedefine + * Marking resolve methods as const + * Refactored AddressSpace::resolve() by creating a new function AddressSpace::checkPointerInObject() that is called in both the forward and the backward searches. This makes the code more modular and removes a large part of duplicated code and should also address the non-deterministic coverage in the resolve() function which affects Codecov reports. + * Fix a crash when the last running state is terminated during merging + * Changed code to create up to 100 properly-numbered symbolic arguments, and add a corresponding check. + * Add checks for correct usage of the POSIX model, together with an associated test. + * Revert lit to 0.6.0 version, as 0.7.0 misbehaves +- removed (in upstream): + * 0001-llvm5-avoid-on-function-arg_begin.patch + * 0002-llvm5-integerPartWidth-is-from-llvm-APFloatBase.patch + * 0003-llvm5-handle-getOrInsertFunction-terminator.patch + * 0004-llvm5-SwitchInst-case-functions-now-return-pointers.patch + * 0005-llvm5-handle-new-file_magic-s-location.patch + * 0006-llvm5-use-MutableArrayRef-for-APFloat-convertToInteg.patch + * 0007-llvm5-Intrinsic-objectsize-has-three-arguments.patch + * 0008-llvm5-test-change-objectsize.patch + * 0009-llvm5-test-add-disable-O0-optnone-to-O0.patch + * 0010-llvm5-CallSite.paramHasAttr-is-indexed-from-0.patch + * 0011-llvm6-SetVersionPrinter-now-passes-down-a-stream.patch + * 0012-llvm6-handle-headers-renaming.patch + +------------------------------------------------------------------- Old: ---- 0001-llvm5-avoid-on-function-arg_begin.patch 0002-llvm5-integerPartWidth-is-from-llvm-APFloatBase.patch 0003-llvm5-handle-getOrInsertFunction-terminator.patch 0004-llvm5-SwitchInst-case-functions-now-return-pointers.patch 0005-llvm5-handle-new-file_magic-s-location.patch 0006-llvm5-use-MutableArrayRef-for-APFloat-convertToInteg.patch 0007-llvm5-Intrinsic-objectsize-has-three-arguments.patch 0008-llvm5-test-change-objectsize.patch 0009-llvm5-test-add-disable-O0-optnone-to-O0.patch 0010-llvm5-CallSite.paramHasAttr-is-indexed-from-0.patch 0011-llvm6-SetVersionPrinter-now-passes-down-a-stream.patch 0012-llvm6-handle-headers-renaming.patch klee-1.4.0+20180920.tar.xz New: ---- disable-failing-test.patch klee-1.4.0+20181026.tar.xz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ klee.spec ++++++ --- /var/tmp/diff_new_pack.idXiMj/_old 2018-12-04 20:57:24.256648195 +0100 +++ /var/tmp/diff_new_pack.idXiMj/_new 2018-12-04 20:57:24.260648190 +0100 @@ -1,7 +1,7 @@ # # spec file for package klee # -# Copyright (c) 2014 SUSE LINUX Products GmbH, Nuernberg, Germany. +# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -12,14 +12,15 @@ # license that conforms to the Open Source Definition (Version 1.9) # published by the Open Source Initiative. -# Please submit bugfixes or comments via http://bugs.opensuse.org/ +# Please submit bugfixes or comments via https://bugs.opensuse.org/ # -%define llvm_version_major 6 + +%define llvm_version_major 7 %define llvm_version_minor 0 %define llvm_version %{llvm_version_major} -%define version_unconverted 1.4.0+20180920 +%define version_unconverted 1.4.0+20181026 %ifarch %{ix86} x86_64 %define with_uclibc 1 @@ -31,26 +32,14 @@ Summary: LLVM Execution Engine License: NCSA Group: Development/Languages/Other -Version: 1.4.0+20180920 +Version: 1.4.0+20181026 Release: 0 Url: http://klee.github.io/ Source0: %{name}-%{version}.tar.xz Source1: %{name}-rpmlintrc Source2: https://raw.githubusercontent.com/llvm-mirror/llvm/release_%{llvm_version_major}%{llvm_version_minor}/utils/not/not.cpp Source3: https://raw.githubusercontent.com/llvm-mirror/llvm/release_%{llvm_version_major}%{llvm_version_minor}/utils/FileCheck/FileCheck.cpp - -Patch201: 0001-llvm5-avoid-on-function-arg_begin.patch -Patch202: 0002-llvm5-integerPartWidth-is-from-llvm-APFloatBase.patch -Patch203: 0003-llvm5-handle-getOrInsertFunction-terminator.patch -Patch204: 0004-llvm5-SwitchInst-case-functions-now-return-pointers.patch -Patch205: 0005-llvm5-handle-new-file_magic-s-location.patch -Patch206: 0006-llvm5-use-MutableArrayRef-for-APFloat-convertToInteg.patch -Patch207: 0007-llvm5-Intrinsic-objectsize-has-three-arguments.patch -Patch208: 0008-llvm5-test-change-objectsize.patch -Patch209: 0009-llvm5-test-add-disable-O0-optnone-to-O0.patch -Patch210: 0010-llvm5-CallSite.paramHasAttr-is-indexed-from-0.patch -Patch211: 0011-llvm6-SetVersionPrinter-now-passes-down-a-stream.patch -Patch212: 0012-llvm6-handle-headers-renaming.patch +Patch0: disable-failing-test.patch BuildRequires: clang%{llvm_version} BuildRequires: cmake @@ -124,7 +113,9 @@ %files %defattr(-,root,root) -%doc LICENSE.TXT NEWS README.md TODO.txt +%doc NEWS README.md TODO.txt +%license LICENSE.TXT +%{_bindir}/gen-bout %{_bindir}/gen-random-bout %{_bindir}/kleaver %{_bindir}/klee ++++++ FileCheck.cpp ++++++ --- /var/tmp/diff_new_pack.idXiMj/_old 2018-12-04 20:57:24.280648168 +0100 +++ /var/tmp/diff_new_pack.idXiMj/_new 2018-12-04 20:57:24.284648164 +0100 @@ -21,14 +21,14 @@ #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringSet.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/InitLLVM.h" #include "llvm/Support/MemoryBuffer.h" -#include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/Regex.h" -#include "llvm/Support/Signals.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cctype> +#include <list> #include <map> #include <string> #include <system_error> @@ -83,6 +83,28 @@ "do not start with '$' will be reset at the beginning of\n" "each CHECK-LABEL block.")); +static cl::opt<bool> AllowDeprecatedDagOverlap( + "allow-deprecated-dag-overlap", cl::init(false), + cl::desc("Enable overlapping among matches in a group of consecutive\n" + "CHECK-DAG directives. This option is deprecated and is only\n" + "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> VerboseVerbose( + "vv", cl::init(false), + cl::desc("Print information helpful in diagnosing internal FileCheck\n" + "issues. Implies -v.\n")); +static const char * DumpInputEnv = "FILECHECK_DUMP_INPUT_ON_FAILURE"; + +static cl::opt<bool> DumpInputOnFailure( + "dump-input-on-failure", cl::init(std::getenv(DumpInputEnv)), + cl::desc("Dump original input to stderr before failing.\n" + "The value can be also controlled using\n" + "FILECHECK_DUMP_INPUT_ON_FAILURE environment variable.\n")); + typedef cl::list<std::string>::const_iterator prefix_iterator; //===----------------------------------------------------------------------===// @@ -98,6 +120,7 @@ CheckNot, CheckDAG, CheckLabel, + CheckEmpty, /// Indicates the pattern only matches the end of file. This is used for /// trailing CHECK-NOTs. @@ -146,8 +169,11 @@ unsigned LineNumber); size_t Match(StringRef Buffer, size_t &MatchLen, StringMap<StringRef> &VariableTable) const; - void PrintFailureInfo(const SourceMgr &SM, StringRef Buffer, - const StringMap<StringRef> &VariableTable) const; + void PrintVariableUses(const SourceMgr &SM, StringRef Buffer, + const StringMap<StringRef> &VariableTable, + SMRange MatchRange = None) const; + void PrintFuzzyMatch(const SourceMgr &SM, StringRef Buffer, + const StringMap<StringRef> &VariableTable) const; bool hasVariable() const { return !(VariableUses.empty() && VariableDefs.empty()); @@ -185,12 +211,25 @@ PatternStr = PatternStr.substr(0, PatternStr.size() - 1); // Check that there is something on the line. - if (PatternStr.empty()) { + if (PatternStr.empty() && CheckTy != Check::CheckEmpty) { SM.PrintMessage(PatternLoc, SourceMgr::DK_Error, "found empty check string with prefix '" + Prefix + ":'"); return true; } + if (!PatternStr.empty() && CheckTy == Check::CheckEmpty) { + SM.PrintMessage( + PatternLoc, SourceMgr::DK_Error, + "found non-empty check string for empty check with prefix '" + Prefix + + ":'"); + return true; + } + + if (CheckTy == Check::CheckEmpty) { + RegExStr = "(\n$)"; + return false; + } + // Check to see if this is a fixed string, or if it has regex pieces. if (!MatchFullLinesHere && (PatternStr.size() < 2 || (PatternStr.find("{{") == StringRef::npos && @@ -463,8 +502,12 @@ VariableTable[VariableDef.first] = MatchInfo[VariableDef.second]; } - MatchLen = FullMatch.size(); - return FullMatch.data() - Buffer.data(); + // Like CHECK-NEXT, CHECK-EMPTY's match range is considered to start after + // the required preceding newline, which is consumed by the pattern in the + // case of CHECK-EMPTY but not CHECK-NEXT. + size_t MatchStartSkip = CheckTy == Check::CheckEmpty; + MatchLen = FullMatch.size() - MatchStartSkip; + return FullMatch.data() - Buffer.data() + MatchStartSkip; } @@ -490,11 +533,9 @@ return BufferPrefix.edit_distance(ExampleString); } -/// Prints additional information about a failure to match involving this -/// pattern. -void Pattern::PrintFailureInfo( - const SourceMgr &SM, StringRef Buffer, - const StringMap<StringRef> &VariableTable) const { +void Pattern::PrintVariableUses(const SourceMgr &SM, StringRef Buffer, + const StringMap<StringRef> &VariableTable, + SMRange MatchRange) const { // If this was a regular expression using variables, print the current // variable values. if (!VariableUses.empty()) { @@ -526,11 +567,19 @@ } } - SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note, - OS.str()); + if (MatchRange.isValid()) + SM.PrintMessage(MatchRange.Start, SourceMgr::DK_Note, OS.str(), + {MatchRange}); + else + SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), + SourceMgr::DK_Note, OS.str()); } } +} +void Pattern::PrintFuzzyMatch( + const SourceMgr &SM, StringRef Buffer, + const StringMap<StringRef> &VariableTable) const { // Attempt to find the closest/best fuzzy match. Usually an error happens // because some string in the output didn't exactly match. In these cases, we // would like to show the user a best guess at what "should have" matched, to @@ -710,6 +759,9 @@ case Check::CheckLabel: return sizeof("-LABEL:") - 1; + case Check::CheckEmpty: + return sizeof("-EMPTY:") - 1; + case Check::CheckEOF: llvm_unreachable("Should not be using EOF size"); } @@ -717,7 +769,37 @@ llvm_unreachable("Bad check type"); } +// Get a description of the type. +static std::string CheckTypeName(StringRef Prefix, Check::CheckType Ty) { + switch (Ty) { + case Check::CheckNone: + return "invalid"; + case Check::CheckPlain: + return Prefix; + case Check::CheckNext: + return Prefix.str() + "-NEXT"; + case Check::CheckSame: + return Prefix.str() + "-SAME"; + case Check::CheckNot: + return Prefix.str() + "-NOT"; + case Check::CheckDAG: + return Prefix.str() + "-DAG"; + case Check::CheckLabel: + return Prefix.str() + "-LABEL"; + case Check::CheckEmpty: + return Prefix.str() + "-EMPTY"; + case Check::CheckEOF: + return "implicit EOF"; + case Check::CheckBadNot: + return "bad NOT"; + } + llvm_unreachable("unknown CheckType"); +} + static Check::CheckType FindCheckType(StringRef Buffer, StringRef Prefix) { + if (Buffer.size() <= Prefix.size()) + return Check::CheckNone; + char NextChar = Buffer[Prefix.size()]; // Verify that the : is present after the prefix. @@ -743,10 +825,14 @@ if (Rest.startswith("LABEL:")) return Check::CheckLabel; + if (Rest.startswith("EMPTY:")) + return Check::CheckEmpty; + // You can't combine -NOT with another suffix. if (Rest.startswith("DAG-NOT:") || Rest.startswith("NOT-DAG:") || Rest.startswith("NEXT-NOT:") || Rest.startswith("NOT-NEXT:") || - Rest.startswith("SAME-NOT:") || Rest.startswith("NOT-SAME:")) + Rest.startswith("SAME-NOT:") || Rest.startswith("NOT-SAME:") || + Rest.startswith("EMPTY-NOT:") || Rest.startswith("NOT-EMPTY:")) return Check::CheckBadNot; return Check::CheckNone; @@ -906,10 +992,13 @@ Buffer = Buffer.substr(EOL); - // Verify that CHECK-NEXT lines have at least one CHECK line before them. - if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame) && + // Verify that CHECK-NEXT/SAME/EMPTY lines have at least one CHECK line before them. + if ((CheckTy == Check::CheckNext || CheckTy == Check::CheckSame || + CheckTy == Check::CheckEmpty) && CheckStrings.empty()) { - StringRef Type = CheckTy == Check::CheckNext ? "NEXT" : "SAME"; + StringRef Type = CheckTy == Check::CheckNext + ? "NEXT" + : CheckTy == Check::CheckEmpty ? "EMPTY" : "SAME"; SM.PrintMessage(SMLoc::getFromPointer(UsedPrefixStart), SourceMgr::DK_Error, "found '" + UsedPrefix + "-" + Type + @@ -956,12 +1045,49 @@ return false; } -static void PrintCheckFailed(const SourceMgr &SM, SMLoc Loc, const Pattern &Pat, - StringRef Buffer, - StringMap<StringRef> &VariableTable) { +static void PrintMatch(bool ExpectedMatch, const SourceMgr &SM, + StringRef Prefix, SMLoc Loc, const Pattern &Pat, + StringRef Buffer, StringMap<StringRef> &VariableTable, + size_t MatchPos, size_t MatchLen) { + if (ExpectedMatch) { + if (!Verbose) + return; + if (!VerboseVerbose && Pat.getCheckTy() == Check::CheckEOF) + return; + } + SMLoc MatchStart = SMLoc::getFromPointer(Buffer.data() + MatchPos); + SMLoc MatchEnd = SMLoc::getFromPointer(Buffer.data() + MatchPos + MatchLen); + SMRange MatchRange(MatchStart, MatchEnd); + SM.PrintMessage( + Loc, ExpectedMatch ? SourceMgr::DK_Remark : SourceMgr::DK_Error, + CheckTypeName(Prefix, Pat.getCheckTy()) + ": " + + (ExpectedMatch ? "expected" : "excluded") + + " string found in input"); + SM.PrintMessage(MatchStart, SourceMgr::DK_Note, "found here", {MatchRange}); + Pat.PrintVariableUses(SM, Buffer, VariableTable, MatchRange); +} + +static void PrintMatch(bool ExpectedMatch, const SourceMgr &SM, + const CheckString &CheckStr, StringRef Buffer, + StringMap<StringRef> &VariableTable, size_t MatchPos, + size_t MatchLen) { + PrintMatch(ExpectedMatch, SM, CheckStr.Prefix, CheckStr.Loc, CheckStr.Pat, + Buffer, VariableTable, MatchPos, MatchLen); +} + +static void PrintNoMatch(bool ExpectedMatch, const SourceMgr &SM, + StringRef Prefix, SMLoc Loc, const Pattern &Pat, + StringRef Buffer, + StringMap<StringRef> &VariableTable) { + if (!ExpectedMatch && !VerboseVerbose) + return; + // Otherwise, we have an error, emit an error message. - SM.PrintMessage(Loc, SourceMgr::DK_Error, - "expected string not found in input"); + SM.PrintMessage(Loc, + ExpectedMatch ? SourceMgr::DK_Error : SourceMgr::DK_Remark, + CheckTypeName(Prefix, Pat.getCheckTy()) + ": " + + (ExpectedMatch ? "expected" : "excluded") + + " string not found in input"); // Print the "scanning from here" line. If the current position is at the // end of a line, advance to the start of the next line. @@ -971,13 +1097,16 @@ "scanning from here"); // Allow the pattern to print additional information if desired. - Pat.PrintFailureInfo(SM, Buffer, VariableTable); + Pat.PrintVariableUses(SM, Buffer, VariableTable); + if (ExpectedMatch) + Pat.PrintFuzzyMatch(SM, Buffer, VariableTable); } -static void PrintCheckFailed(const SourceMgr &SM, const CheckString &CheckStr, - StringRef Buffer, - StringMap<StringRef> &VariableTable) { - PrintCheckFailed(SM, CheckStr.Loc, CheckStr.Pat, Buffer, VariableTable); +static void PrintNoMatch(bool ExpectedMatch, const SourceMgr &SM, + const CheckString &CheckStr, StringRef Buffer, + StringMap<StringRef> &VariableTable) { + PrintNoMatch(ExpectedMatch, SM, CheckStr.Prefix, CheckStr.Loc, CheckStr.Pat, + Buffer, VariableTable); } /// Count the number of newlines in the specified range. @@ -1025,9 +1154,10 @@ StringRef MatchBuffer = Buffer.substr(LastPos); size_t MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable); if (MatchPos == StringRef::npos) { - PrintCheckFailed(SM, *this, MatchBuffer, VariableTable); + PrintNoMatch(true, SM, *this, MatchBuffer, VariableTable); return StringRef::npos; } + PrintMatch(true, SM, *this, MatchBuffer, VariableTable, MatchPos, MatchLen); // Similar to the above, in "label-scan mode" we can't yet handle CHECK-NEXT // or CHECK-NOT @@ -1055,22 +1185,27 @@ /// Verify there is a single line in the given buffer. bool CheckString::CheckNext(const SourceMgr &SM, StringRef Buffer) const { - if (Pat.getCheckTy() != Check::CheckNext) + if (Pat.getCheckTy() != Check::CheckNext && + Pat.getCheckTy() != Check::CheckEmpty) return false; + Twine CheckName = + Prefix + + Twine(Pat.getCheckTy() == Check::CheckEmpty ? "-EMPTY" : "-NEXT"); + // Count the number of newlines between the previous match and this one. assert(Buffer.data() != SM.getMemoryBuffer(SM.FindBufferContainingLoc( SMLoc::getFromPointer(Buffer.data()))) ->getBufferStart() && - "CHECK-NEXT can't be the first check in a file"); + "CHECK-NEXT and CHECK-EMPTY can't be the first check in a file"); const char *FirstNewLine = nullptr; unsigned NumNewLines = CountNumNewlinesBetween(Buffer, FirstNewLine); if (NumNewLines == 0) { SM.PrintMessage(Loc, SourceMgr::DK_Error, - Prefix + "-NEXT: is on the same line as previous match"); + CheckName + ": is on the same line as previous match"); SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note, "'next' match was here"); SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note, @@ -1080,8 +1215,8 @@ if (NumNewLines != 1) { SM.PrintMessage(Loc, SourceMgr::DK_Error, - Prefix + - "-NEXT: is not on the line after the previous match"); + CheckName + + ": is not on the line after the previous match"); SM.PrintMessage(SMLoc::getFromPointer(Buffer.end()), SourceMgr::DK_Note, "'next' match was here"); SM.PrintMessage(SMLoc::getFromPointer(Buffer.data()), SourceMgr::DK_Note, @@ -1133,13 +1268,15 @@ size_t MatchLen = 0; size_t Pos = Pat->Match(Buffer, MatchLen, VariableTable); - if (Pos == StringRef::npos) + if (Pos == StringRef::npos) { + PrintNoMatch(false, SM, Prefix, Pat->getLoc(), *Pat, Buffer, + VariableTable); continue; + } + + PrintMatch(false, SM, Prefix, Pat->getLoc(), *Pat, Buffer, VariableTable, + Pos, MatchLen); - SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + Pos), - SourceMgr::DK_Error, Prefix + "-NOT: string occurred!"); - SM.PrintMessage(Pat->getLoc(), SourceMgr::DK_Note, - Prefix + "-NOT: pattern specified here"); return true; } @@ -1153,10 +1290,23 @@ if (DagNotStrings.empty()) return 0; - size_t LastPos = 0; - size_t StartPos = LastPos; + // The start of the search range. + size_t StartPos = 0; - for (const Pattern &Pat : DagNotStrings) { + struct MatchRange { + size_t Pos; + size_t End; + }; + // A sorted list of ranges for non-overlapping CHECK-DAG matches. Match + // ranges are erased from this list once they are no longer in the search + // range. + std::list<MatchRange> MatchRanges; + + // We need PatItr and PatEnd later for detecting the end of a CHECK-DAG + // group, so we don't use a range-based for loop here. + for (auto PatItr = DagNotStrings.begin(), PatEnd = DagNotStrings.end(); + PatItr != PatEnd; ++PatItr) { + const Pattern &Pat = *PatItr; assert((Pat.getCheckTy() == Check::CheckDAG || Pat.getCheckTy() == Check::CheckNot) && "Invalid CHECK-DAG or CHECK-NOT!"); @@ -1168,57 +1318,92 @@ assert((Pat.getCheckTy() == Check::CheckDAG) && "Expect CHECK-DAG!"); - size_t MatchLen = 0, MatchPos; - // CHECK-DAG always matches from the start. - StringRef MatchBuffer = Buffer.substr(StartPos); - MatchPos = Pat.Match(MatchBuffer, MatchLen, VariableTable); - // With a group of CHECK-DAGs, a single mismatching means the match on - // that group of CHECK-DAGs fails immediately. - if (MatchPos == StringRef::npos) { - PrintCheckFailed(SM, Pat.getLoc(), Pat, MatchBuffer, VariableTable); - return StringRef::npos; - } - // Re-calc it as the offset relative to the start of the original string. - MatchPos += StartPos; + size_t MatchLen = 0, MatchPos = StartPos; - if (!NotStrings.empty()) { - if (MatchPos < LastPos) { - // Reordered? - SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + MatchPos), - SourceMgr::DK_Error, - Prefix + "-DAG: found a match of CHECK-DAG" - " reordering across a CHECK-NOT"); - SM.PrintMessage(SMLoc::getFromPointer(Buffer.data() + LastPos), - SourceMgr::DK_Note, - Prefix + "-DAG: the farthest match of CHECK-DAG" - " is found here"); - SM.PrintMessage(NotStrings[0]->getLoc(), SourceMgr::DK_Note, - Prefix + "-NOT: the crossed pattern specified" - " here"); - SM.PrintMessage(Pat.getLoc(), SourceMgr::DK_Note, - Prefix + "-DAG: the reordered pattern specified" - " here"); + // Search for a match that doesn't overlap a previous match in this + // CHECK-DAG group. + for (auto MI = MatchRanges.begin(), ME = MatchRanges.end(); true; ++MI) { + StringRef MatchBuffer = Buffer.substr(MatchPos); + size_t MatchPosBuf = Pat.Match(MatchBuffer, MatchLen, VariableTable); + // With a group of CHECK-DAGs, a single mismatching means the match on + // that group of CHECK-DAGs fails immediately. + if (MatchPosBuf == StringRef::npos) { + PrintNoMatch(true, SM, Prefix, Pat.getLoc(), Pat, MatchBuffer, + VariableTable); return StringRef::npos; } - // All subsequent CHECK-DAGs should be matched from the farthest - // position of all precedent CHECK-DAGs (including this one.) - StartPos = LastPos; - // If there's CHECK-NOTs between two CHECK-DAGs or from CHECK to - // CHECK-DAG, verify that there's no 'not' strings occurred in that - // region. - StringRef SkippedRegion = Buffer.slice(LastPos, MatchPos); - if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable)) - return StringRef::npos; - // Clear "not strings". - NotStrings.clear(); + // Re-calc it as the offset relative to the start of the original string. + MatchPos += MatchPosBuf; + if (VerboseVerbose) + PrintMatch(true, SM, Prefix, Pat.getLoc(), Pat, Buffer, VariableTable, + MatchPos, MatchLen); + MatchRange M{MatchPos, MatchPos + MatchLen}; + if (AllowDeprecatedDagOverlap) { + // We don't need to track all matches in this mode, so we just maintain + // one match range that encompasses the current CHECK-DAG group's + // matches. + if (MatchRanges.empty()) + MatchRanges.insert(MatchRanges.end(), M); + else { + auto Block = MatchRanges.begin(); + Block->Pos = std::min(Block->Pos, M.Pos); + Block->End = std::max(Block->End, M.End); + } + break; + } + // Iterate previous matches until overlapping match or insertion point. + bool Overlap = false; + for (; MI != ME; ++MI) { + if (M.Pos < MI->End) { + // !Overlap => New match has no overlap and is before this old match. + // Overlap => New match overlaps this old match. + Overlap = MI->Pos < M.End; + break; + } + } + if (!Overlap) { + // Insert non-overlapping match into list. + MatchRanges.insert(MI, M); + break; + } + if (VerboseVerbose) { + SMLoc OldStart = SMLoc::getFromPointer(Buffer.data() + MI->Pos); + SMLoc OldEnd = SMLoc::getFromPointer(Buffer.data() + MI->End); + SMRange OldRange(OldStart, OldEnd); + SM.PrintMessage(OldStart, SourceMgr::DK_Note, + "match discarded, overlaps earlier DAG match here", + {OldRange}); + } + MatchPos = MI->End; + } + if (!VerboseVerbose) + PrintMatch(true, SM, Prefix, Pat.getLoc(), Pat, Buffer, VariableTable, + MatchPos, MatchLen); + + // Handle the end of a CHECK-DAG group. + if (std::next(PatItr) == PatEnd || + std::next(PatItr)->getCheckTy() == Check::CheckNot) { + if (!NotStrings.empty()) { + // If there are CHECK-NOTs between two CHECK-DAGs or from CHECK to + // CHECK-DAG, verify that there are no 'not' strings occurred in that + // region. + StringRef SkippedRegion = + Buffer.slice(StartPos, MatchRanges.begin()->Pos); + if (CheckNot(SM, SkippedRegion, NotStrings, VariableTable)) + return StringRef::npos; + // Clear "not strings". + NotStrings.clear(); + } + // All subsequent CHECK-DAGs and CHECK-NOTs should be matched from the + // end of this CHECK-DAG group's match range. + StartPos = MatchRanges.rbegin()->End; + // Don't waste time checking for (impossible) overlaps before that. + MatchRanges.clear(); } - - // Update the last position with CHECK-DAG matches. - LastPos = std::max(MatchPos + MatchLen, LastPos); } - return LastPos; + return StartPos; } // A check prefix must contain only alphanumeric, hyphens and underscores. @@ -1357,8 +1542,7 @@ } int main(int argc, char **argv) { - sys::PrintStackTraceOnErrorSignal(argv[0]); - PrettyStackTraceProgram X(argc, argv); + InitLLVM X(argc, argv); cl::ParseCommandLineOptions(argc, argv); if (!ValidateCheckPrefixes()) { @@ -1379,6 +1563,9 @@ return 2; } + if (VerboseVerbose) + Verbose = true; + SourceMgr SM; // Read the expected strings from the check file. @@ -1425,5 +1612,9 @@ InputFileText, InputFile.getBufferIdentifier()), SMLoc()); - return CheckInput(SM, InputFileText, CheckStrings) ? EXIT_SUCCESS : 1; + int ExitCode = CheckInput(SM, InputFileText, CheckStrings) ? EXIT_SUCCESS : 1; + if (ExitCode == 1 && DumpInputOnFailure) + errs() << "Full input was:\n<<<<<<\n" << InputFileText << "\n>>>>>>\n"; + + return ExitCode; } ++++++ _servicedata ++++++ --- /var/tmp/diff_new_pack.idXiMj/_old 2018-12-04 20:57:24.312648133 +0100 +++ /var/tmp/diff_new_pack.idXiMj/_new 2018-12-04 20:57:24.312648133 +0100 @@ -1,4 +1,4 @@ <servicedata> <service name="tar_scm"> <param name="url">git://github.com/klee/klee.git</param> - <param name="changesrevision">4efd7f6b443f187f5a844227339383ce5593e865</param></service></servicedata> \ No newline at end of file + <param name="changesrevision">581dca9276cacc690703cd4962e309661fc71c23</param></service></servicedata> \ No newline at end of file ++++++ disable-failing-test.patch ++++++ Just temporarily... https://github.com/klee/klee/issues/1010 --- test/Runtime/POSIX/DirConsistency.c | 1 + 1 file changed, 1 insertion(+) --- a/test/Runtime/POSIX/DirConsistency.c +++ b/test/Runtime/POSIX/DirConsistency.c @@ -1,3 +1,4 @@ +// REQUIRES: bubak // RUN: %llvmgcc %s -emit-llvm %O0opt -c -o %t.bc // RUN: rm -rf %t.klee-out %t.klee-out-tmp // RUN: %gentmp %t.klee-out-tmp ++++++ klee-1.4.0+20180920.tar.xz -> klee-1.4.0+20181026.tar.xz ++++++ ++++ 8269 lines of diff (skipped) ++++++ not.cpp ++++++ --- /var/tmp/diff_new_pack.idXiMj/_old 2018-12-04 20:57:24.808647586 +0100 +++ /var/tmp/diff_new_pack.idXiMj/_new 2018-12-04 20:57:24.808647586 +0100 @@ -38,8 +38,12 @@ return 1; } + std::vector<StringRef> Argv; + Argv.reserve(argc); + for (int i = 0; i < argc; ++i) + Argv.push_back(argv[i]); std::string ErrMsg; - int Result = sys::ExecuteAndWait(*Program, argv, nullptr, {}, 0, 0, &ErrMsg); + int Result = sys::ExecuteAndWait(*Program, Argv, None, {}, 0, 0, &ErrMsg); #ifdef _WIN32 // Handle abort() in msvcrt -- It has exit code as 3. abort(), aka // unreachable, should be recognized as a crash. However, some binaries use