Hello community,

here is the log from the commit of package re2 for openSUSE:Factory checked in 
at 2017-12-19 10:59:21
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/re2 (Old)
 and      /work/SRC/openSUSE:Factory/.re2.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "re2"

Tue Dec 19 10:59:21 2017 rev:12 rq:558181 version:MACRO

Changes:
--------
--- /work/SRC/openSUSE:Factory/re2/re2.changes  2017-11-04 19:29:43.820153929 
+0100
+++ /work/SRC/openSUSE:Factory/.re2.new/re2.changes     2017-12-19 
10:59:21.946806415 +0100
@@ -1,0 +2,6 @@
+Mon Dec 18 14:19:37 UTC 2017 - mplus...@suse.com
+
+- Update to version 2017-12-01
+  * No upstream changelog available 
+
+-------------------------------------------------------------------

Old:
----
  2017-11-01.tar.gz

New:
----
  2017-12-01.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ re2.spec ++++++
--- /var/tmp/diff_new_pack.2NxJny/_old  2017-12-19 10:59:22.706769728 +0100
+++ /var/tmp/diff_new_pack.2NxJny/_new  2017-12-19 10:59:22.706769728 +0100
@@ -16,7 +16,7 @@
 #
 
 
-%global longver 2017-11-01
+%global longver 2017-12-01
 %global shortver %(echo %{longver}|sed 's|-||g')
 %define libname libre2-0
 Name:           re2
@@ -25,7 +25,7 @@
 Summary:        C++ fast alternative to backtracking RE engines
 License:        BSD-3-Clause
 Group:          Development/Libraries/C and C++
-Url:            https://github.com/google/re2/
+URL:            https://github.com/google/re2/
 Source0:        https://github.com/google/re2/archive/%{longver}.tar.gz
 BuildRequires:  gcc-c++
 BuildRequires:  pkgconfig

++++++ 2017-11-01.tar.gz -> 2017-12-01.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re2-2017-11-01/re2/prefilter_tree.cc 
new/re2-2017-12-01/re2/prefilter_tree.cc
--- old/re2-2017-11-01/re2/prefilter_tree.cc    2017-10-28 04:16:51.000000000 
+0200
+++ new/re2-2017-12-01/re2/prefilter_tree.cc    2017-11-16 22:52:42.000000000 
+0100
@@ -15,6 +15,7 @@
 
 #include "util/util.h"
 #include "util/logging.h"
+#include "util/strutil.h"
 #include "re2/prefilter.h"
 #include "re2/re2.h"
 
@@ -67,7 +68,9 @@
 
   compiled_ = true;
 
-  AssignUniqueIds(atom_vec);
+  // TODO(junyer): Use std::unordered_set<Prefilter*> instead?
+  NodeMap nodes;
+  AssignUniqueIds(&nodes, atom_vec);
 
   // Identify nodes that are too common among prefilters and are
   // triggering too many parents. Then get rid of them if possible.
@@ -100,27 +103,27 @@
   }
 
   if (ExtraDebug)
-    PrintDebugInfo();
+    PrintDebugInfo(&nodes);
 }
 
-Prefilter* PrefilterTree::CanonicalNode(Prefilter* node) {
+Prefilter* PrefilterTree::CanonicalNode(NodeMap* nodes, Prefilter* node) {
   string node_string = NodeString(node);
-  std::map<string, Prefilter*>::iterator iter = node_map_.find(node_string);
-  if (iter == node_map_.end())
+  std::map<string, Prefilter*>::iterator iter = nodes->find(node_string);
+  if (iter == nodes->end())
     return NULL;
   return (*iter).second;
 }
 
 string PrefilterTree::NodeString(Prefilter* node) const {
   // Adding the operation disambiguates AND/OR/atom nodes.
-  string s = std::to_string(node->op()) + ":";
+  string s = StringPrintf("%d", node->op()) + ":";
   if (node->op() == Prefilter::ATOM) {
     s += node->atom();
   } else {
     for (size_t i = 0; i < node->subs()->size(); i++) {
       if (i > 0)
         s += ',';
-      s += std::to_string((*node->subs())[i]->unique_id());
+      s += StringPrintf("%d", (*node->subs())[i]->unique_id());
     }
   }
   return s;
@@ -162,7 +165,8 @@
   }
 }
 
-void PrefilterTree::AssignUniqueIds(std::vector<string>* atom_vec) {
+void PrefilterTree::AssignUniqueIds(NodeMap* nodes,
+                                    std::vector<string>* atom_vec) {
   atom_vec->clear();
 
   // Build vector of all filter nodes, sorted topologically
@@ -199,11 +203,11 @@
     if (node == NULL)
       continue;
     node->set_unique_id(-1);
-    Prefilter* canonical = CanonicalNode(node);
+    Prefilter* canonical = CanonicalNode(nodes, node);
     if (canonical == NULL) {
       // Any further nodes that have the same node string
       // will find this node as the canonical node.
-      node_map_[NodeString(node)] = node;
+      nodes->emplace(NodeString(node), node);
       if (node->op() == Prefilter::ATOM) {
         atom_vec->push_back(node->atom());
         atom_index_to_id_.push_back(unique_id);
@@ -213,7 +217,7 @@
       node->set_unique_id(canonical->unique_id());
     }
   }
-  entries_.resize(node_map_.size());
+  entries_.resize(nodes->size());
 
   // Create parent StdIntMap for the entries.
   for (int i = static_cast<int>(v.size()) - 1; i >= 0; i--) {
@@ -221,7 +225,7 @@
     if (prefilter == NULL)
       continue;
 
-    if (CanonicalNode(prefilter) != prefilter)
+    if (CanonicalNode(nodes, prefilter) != prefilter)
       continue;
 
     Entry* entry = &entries_[prefilter->unique_id()];
@@ -234,7 +238,7 @@
     if (prefilter == NULL)
       continue;
 
-    if (CanonicalNode(prefilter) != prefilter)
+    if (CanonicalNode(nodes, prefilter) != prefilter)
       continue;
 
     Entry* entry = &entries_[prefilter->unique_id()];
@@ -254,7 +258,7 @@
         std::set<int> uniq_child;
         for (size_t j = 0; j < prefilter->subs()->size(); j++) {
           Prefilter* child = (*prefilter->subs())[j];
-          Prefilter* canonical = CanonicalNode(child);
+          Prefilter* canonical = CanonicalNode(nodes, child);
           if (canonical == NULL) {
             LOG(DFATAL) << "Null canonical node";
             return;
@@ -281,7 +285,7 @@
   for (size_t i = 0; i < prefilter_vec_.size(); i++) {
     if (prefilter_vec_[i] == NULL)
       continue;
-    int id = CanonicalNode(prefilter_vec_[i])->unique_id();
+    int id = CanonicalNode(nodes, prefilter_vec_[i])->unique_id();
     DCHECK_LE(0, id);
     Entry* entry = &entries_[id];
     entry->regexps.push_back(static_cast<int>(i));
@@ -357,7 +361,7 @@
   LOG(ERROR) << DebugNodeString(prefilter_vec_[regexpid]);
 }
 
-void PrefilterTree::PrintDebugInfo() {
+void PrefilterTree::PrintDebugInfo(NodeMap* nodes) {
   LOG(ERROR) << "#Unique Atoms: " << atom_index_to_id_.size();
   LOG(ERROR) << "#Unique Nodes: " << entries_.size();
 
@@ -370,8 +374,8 @@
       LOG(ERROR) << it->first;
   }
   LOG(ERROR) << "Map:";
-  for (std::map<string, Prefilter*>::const_iterator iter = node_map_.begin();
-       iter != node_map_.end(); ++iter)
+  for (std::map<string, Prefilter*>::const_iterator iter = nodes->begin();
+       iter != nodes->end(); ++iter)
     LOG(ERROR) << "NodeId: " << (*iter).second->unique_id()
                << " Str: " << (*iter).first;
 }
@@ -389,7 +393,7 @@
     for (size_t i = 0; i < node->subs()->size(); i++) {
       if (i > 0)
         node_string += ',';
-      node_string += std::to_string((*node->subs())[i]->unique_id());
+      node_string += StringPrintf("%d", (*node->subs())[i]->unique_id());
       node_string += ":";
       node_string += DebugNodeString((*node->subs())[i]);
     }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re2-2017-11-01/re2/prefilter_tree.h 
new/re2-2017-12-01/re2/prefilter_tree.h
--- old/re2-2017-11-01/re2/prefilter_tree.h     2017-10-28 04:16:51.000000000 
+0200
+++ new/re2-2017-12-01/re2/prefilter_tree.h     2017-11-16 22:52:42.000000000 
+0100
@@ -22,14 +22,10 @@
 
 #include "util/util.h"
 #include "util/sparse_array.h"
+#include "re2/prefilter.h"
 
 namespace re2 {
 
-typedef SparseArray<int> IntMap;
-typedef std::map<int, int> StdIntMap;
-
-class Prefilter;
-
 class PrefilterTree {
  public:
   PrefilterTree();
@@ -61,6 +57,10 @@
   // nodes of the prefilter of the regexp.
   void PrintPrefilter(int regexpid);
 
+ private:
+  typedef SparseArray<int> IntMap;
+  typedef std::map<int, int> StdIntMap;
+  typedef std::map<string, Prefilter*> NodeMap;
 
   // Each unique node has a corresponding Entry that helps in
   // passing the matching trigger information along the tree.
@@ -84,14 +84,13 @@
     std::vector<int> regexps;
   };
 
- private:
   // Returns true if the prefilter node should be kept.
   bool KeepNode(Prefilter* node) const;
 
   // This function assigns unique ids to various parts of the
   // prefilter, by looking at if these nodes are already in the
   // PrefilterTree.
-  void AssignUniqueIds(std::vector<string>* atom_vec);
+  void AssignUniqueIds(NodeMap* nodes, std::vector<string>* atom_vec);
 
   // Given the matching atoms, find the regexps to be triggered.
   void PropagateMatch(const std::vector<int>& atom_ids,
@@ -99,7 +98,7 @@
 
   // Returns the prefilter node that has the same NodeString as this
   // node. For the canonical node, returns node.
-  Prefilter* CanonicalNode(Prefilter* node);
+  Prefilter* CanonicalNode(NodeMap* nodes, Prefilter* node);
 
   // A string that uniquely identifies the node. Assumes that the
   // children of node has already been assigned unique ids.
@@ -109,15 +108,12 @@
   string DebugNodeString(Prefilter* node) const;
 
   // Used for debugging.
-  void PrintDebugInfo();
+  void PrintDebugInfo(NodeMap* nodes);
 
   // These are all the nodes formed by Compile. Essentially, there is
   // one node for each unique atom and each unique AND/OR node.
   std::vector<Entry> entries_;
 
-  // Map node string to canonical Prefilter node.
-  std::map<string, Prefilter*> node_map_;
-
   // indices of regexps that always pass through the filter (since we
   // found no required literals in these regexps).
   std::vector<int> unfiltered_;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re2-2017-11-01/re2/set.cc 
new/re2-2017-12-01/re2/set.cc
--- old/re2-2017-11-01/re2/set.cc       2017-10-28 04:16:51.000000000 +0200
+++ new/re2-2017-12-01/re2/set.cc       2017-11-16 22:52:42.000000000 +0100
@@ -104,8 +104,15 @@
 }
 
 bool RE2::Set::Match(const StringPiece& text, std::vector<int>* v) const {
+  return Match(text, v, NULL);
+}
+
+bool RE2::Set::Match(const StringPiece& text, std::vector<int>* v,
+                     ErrorInfo* error_info) const {
   if (!compiled_) {
     LOG(DFATAL) << "RE2::Set::Match() called before compiling";
+    if (error_info != NULL)
+      error_info->kind = kNotCompiled;
     return false;
   }
   bool dfa_failed = false;
@@ -121,17 +128,26 @@
       LOG(ERROR) << "DFA out of memory: size " << prog_->size() << ", "
                  << "bytemap range " << prog_->bytemap_range() << ", "
                  << "list count " << prog_->list_count();
+    if (error_info != NULL)
+      error_info->kind = kOutOfMemory;
     return false;
   }
-  if (ret == false)
+  if (ret == false) {
+    if (error_info != NULL)
+      error_info->kind = kNoError;
     return false;
+  }
   if (v != NULL) {
     if (matches->empty()) {
-      LOG(DFATAL) << "RE2::Set::Match() matched, but matches unknown";
+      LOG(DFATAL) << "RE2::Set::Match() matched, but no matches returned?!";
+      if (error_info != NULL)
+        error_info->kind = kInconsistent;
       return false;
     }
     v->assign(matches->begin(), matches->end());
   }
+  if (error_info != NULL)
+    error_info->kind = kNoError;
   return true;
 }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re2-2017-11-01/re2/set.h new/re2-2017-12-01/re2/set.h
--- old/re2-2017-11-01/re2/set.h        2017-10-28 04:16:51.000000000 +0200
+++ new/re2-2017-12-01/re2/set.h        2017-11-16 22:52:42.000000000 +0100
@@ -22,29 +22,45 @@
 // be searched for simultaneously.
 class RE2::Set {
  public:
+  enum ErrorKind {
+    kNoError = 0,
+    kNotCompiled,   // The set is not compiled.
+    kOutOfMemory,   // The DFA ran out of memory.
+    kInconsistent,  // The result is inconsistent. This should never happen.
+  };
+
+  struct ErrorInfo {
+    ErrorKind kind;
+  };
+
   Set(const RE2::Options& options, RE2::Anchor anchor);
   ~Set();
 
-  // Add adds regexp pattern to the set, interpreted using the RE2 options.
-  // (The RE2 constructor's default options parameter is RE2::UTF8.)
-  // Add returns the regexp index that will be used to identify
-  // it in the result of Match, or -1 if the regexp cannot be parsed.
+  // Adds pattern to the set using the options passed to the constructor.
+  // Returns the index that will identify the regexp in the output of Match(),
+  // or -1 if the regexp cannot be parsed.
   // Indices are assigned in sequential order starting from 0.
-  // Error returns do not increment the index.
-  // If an error occurs and error != NULL, *error will hold an error message.
+  // Errors do not increment the index; if error is not NULL, *error will hold
+  // the error message from the parser.
   int Add(const StringPiece& pattern, string* error);
 
-  // Compile prepares the Set for matching.
-  // Add must not be called again after Compile.
-  // Compile must be called before Match.
-  // Compile may return false if it runs out of memory.
+  // Compiles the set in preparation for matching.
+  // Returns false if the compiler runs out of memory.
+  // Add() must not be called again after Compile().
+  // Compile() must be called before Match().
   bool Compile();
 
-  // Match returns true if text matches any of the regexps in the set.
-  // If so, it fills v (if not NULL) with the indices of the matching regexps.
+  // Returns true if text matches at least one of the regexps in the set.
+  // Fills v (if not NULL) with the indices of the matching regexps.
   // Callers must not expect v to be sorted.
   bool Match(const StringPiece& text, std::vector<int>* v) const;
 
+  // As above, but populates error_info (if not NULL) when none of the regexps
+  // in the set matched. This can inform callers when DFA execution fails, for
+  // example, because they might wish to handle that case differently.
+  bool Match(const StringPiece& text, std::vector<int>* v,
+             ErrorInfo* error_info) const;
+
  private:
   typedef std::pair<string, re2::Regexp*> Elem;
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re2-2017-11-01/re2/testing/set_test.cc 
new/re2-2017-12-01/re2/testing/set_test.cc
--- old/re2-2017-11-01/re2/testing/set_test.cc  2017-10-28 04:16:51.000000000 
+0200
+++ new/re2-2017-12-01/re2/testing/set_test.cc  2017-11-16 22:52:42.000000000 
+0100
@@ -3,6 +3,7 @@
 // license that can be found in the LICENSE file.
 
 #include <stddef.h>
+#include <string>
 #include <vector>
 
 #include "util/test.h"
@@ -200,4 +201,18 @@
   CHECK_EQ(v[0], 0);
 }
 
+TEST(Set, OutOfMemory) {
+  RE2::Set s(RE2::DefaultOptions, RE2::UNANCHORED);
+
+  string a(10000, 'a');
+  CHECK_EQ(s.Add(a, NULL), 0);
+  CHECK_EQ(s.Compile(), true);
+
+  std::vector<int> v;
+  RE2::Set::ErrorInfo ei;
+  CHECK_EQ(s.Match(a, &v, &ei), false);
+  CHECK_EQ(v.size(), 0);
+  CHECK_EQ(ei.kind, RE2::Set::kOutOfMemory);
+}
+
 }  // namespace re2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re2-2017-11-01/util/sparse_array.h 
new/re2-2017-12-01/util/sparse_array.h
--- old/re2-2017-11-01/util/sparse_array.h      2017-10-28 04:16:51.000000000 
+0200
+++ new/re2-2017-12-01/util/sparse_array.h      2017-11-16 22:52:42.000000000 
+0100
@@ -55,36 +55,34 @@
 
 // IMPLEMENTATION
 //
-// SparseArray uses a vector dense_ and an array sparse_to_dense_, both of
-// size max_size_. At any point, the number of elements in the sparse array is
-// size_.
+// SparseArray is an array dense_ and an array sparse_, both of size max_size_.
+// At any point, the number of elements in the sparse array is size_.
 //
-// The vector dense_ contains the size_ elements in the sparse array (with
+// The array dense_ contains the size_ elements in the sparse array (with
 // their indices),
 // in the order that the elements were first inserted.  This array is dense:
 // the size_ pairs are dense_[0] through dense_[size_-1].
 //
-// The array sparse_to_dense_ maps from indices in [0,m) to indices in
-// [0,size_).
-// For indices present in the array, dense_[sparse_to_dense_[i]].index_ == i.
-// For indices not present in the array, sparse_to_dense_ can contain
-// any value at all, perhaps outside the range [0, size_) but perhaps not.
+// The array sparse_ maps from indices in [0,m) to indices in [0,size_).
+// For indices present in the array, dense_[sparse_[i]].index_ == i.
+// For indices not present in the array, sparse_ can contain any value at all,
+// perhaps outside the range [0, size_) but perhaps not.
 //
-// The lax requirement on sparse_to_dense_ values makes clearing
-// the array very easy: set size_ to 0.  Lookups are slightly more
-// complicated.  An index i has a value in the array if and only if:
-//   sparse_to_dense_[i] is in [0, size_) AND
-//   dense_[sparse_to_dense_[i]].index_ == i.
+// The lax requirement on sparse_ values makes clearing the array very easy:
+// set size_ to 0.  Lookups are slightly more complicated.
+// An index i has a value in the array if and only if:
+//   sparse_[i] is in [0, size_) AND
+//   dense_[sparse_[i]].index_ == i.
 // If both these properties hold, only then it is safe to refer to
-//   dense_[sparse_to_dense_[i]].value_
+//   dense_[sparse_[i]].value_
 // as the value associated with index i.
 //
-// To insert a new entry, set sparse_to_dense_[i] to size_,
+// To insert a new entry, set sparse_[i] to size_,
 // initialize dense_[size_], and then increment size_.
 //
 // Deletion of specific values from the array is implemented by
 // swapping dense_[size_-1] and the dense_ being deleted and then
-// updating the appropriate sparse_to_dense_ entries.
+// updating the appropriate sparse_ entries.
 //
 // To make the sparse array as efficient as possible for non-primitive types,
 // elements may or may not be destroyed when they are deleted from the sparse
@@ -94,9 +92,17 @@
 //
 // A moved-from SparseArray will be empty.
 
+// Doing this simplifies the logic below.
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
 #include <assert.h>
 #include <stdint.h>
 #include <string.h>
+#if __has_feature(memory_sanitizer)
+#include <sanitizer/msan_interface.h>
+#endif
 #include <algorithm>
 #include <memory>
 #include <type_traits>
@@ -200,13 +206,13 @@
 
   iterator find(int i) {
     if (has_index(i))
-      return dense_.get() + sparse_to_dense_[i];
+      return dense_.get() + sparse_[i];
     return end();
   }
 
   const_iterator find(int i) const {
     if (has_index(i))
-      return dense_.get() + sparse_to_dense_[i];
+      return dense_.get() + sparse_[i];
     return end();
   }
 
@@ -263,7 +269,7 @@
     DebugCheckInvariants();
     std::pair<iterator, bool> p;
     if (has_index(v.index_)) {
-      p = {dense_.get() + sparse_to_dense_[v.index_], false};
+      p = {dense_.get() + sparse_[v.index_], false};
     } else {
       p = {set_new(std::forward<U>(v).index_, std::forward<U>(v).second), 
true};
     }
@@ -295,9 +301,9 @@
   iterator SetExistingInternal(int i, U&& v) {  // NOLINT
     DebugCheckInvariants();
     assert(has_index(i));
-    dense_[sparse_to_dense_[i]].value() = std::forward<U>(v);
+    dense_[sparse_[i]].value() = std::forward<U>(v);
     DebugCheckInvariants();
-    return dense_.get() + sparse_to_dense_[i];
+    return dense_.get() + sparse_[i];
   }
 
   // Add the index i to the array.
@@ -312,23 +318,20 @@
   // and at the beginning and end of all public non-const member functions.
   void DebugCheckInvariants() const;
 
-  static bool ShouldInitializeMemory() {
-#if defined(__has_feature)
+  // Initializes memory for elements [min, max).
+  void MaybeInitializeMemory(int min, int max) {
 #if __has_feature(memory_sanitizer)
-    return true;
-#else
-    return false;
-#endif
+    __msan_unpoison(sparse_.get() + min, (max - min) * sizeof sparse_[0]);
 #elif defined(RE2_ON_VALGRIND)
-    return true;
-#else
-    return false;
+    for (int i = min; i < max; i++) {
+      sparse_[i] = 0xababababU;
+    }
 #endif
   }
 
   int size_ = 0;
   int max_size_ = 0;
-  std::unique_ptr<int[]> sparse_to_dense_;
+  std::unique_ptr<int[]> sparse_;
   std::unique_ptr<IndexValue[]> dense_;
 };
 
@@ -339,9 +342,9 @@
 SparseArray<Value>::SparseArray(const SparseArray& src)
     : size_(src.size_),
       max_size_(src.max_size_),
-      sparse_to_dense_(new int[max_size_]),
+      sparse_(new int[max_size_]),
       dense_(new IndexValue[max_size_]) {
-  std::copy_n(src.sparse_to_dense_.get(), max_size_, sparse_to_dense_.get());
+  std::copy_n(src.sparse_.get(), max_size_, sparse_.get());
   std::copy_n(src.dense_.get(), max_size_, dense_.get());
 }
 
@@ -349,7 +352,7 @@
 SparseArray<Value>::SparseArray(SparseArray&& src) /*noexcept*/  // NOLINT
     : size_(src.size_),
       max_size_(src.max_size_),
-      sparse_to_dense_(std::move(src.sparse_to_dense_)),
+      sparse_(std::move(src.sparse_)),
       dense_(std::move(src.dense_)) {
   src.size_ = 0;
   src.max_size_ = 0;
@@ -360,8 +363,8 @@
   size_ = src.size_;
   max_size_ = src.max_size_;
   std::unique_ptr<int[]> a(new int[max_size_]);
-  std::copy_n(src.sparse_to_dense_.get(), src.max_size_, a.get());
-  sparse_to_dense_ = std::move(a);
+  std::copy_n(src.sparse_.get(), src.max_size_, a.get());
+  sparse_ = std::move(a);
   std::unique_ptr<IndexValue[]> b(new IndexValue[max_size_]);
   std::copy_n(src.dense_.get(), src.max_size_, b.get());
   dense_ = std::move(b);
@@ -373,7 +376,7 @@
     SparseArray&& src) /*noexcept*/ {  // NOLINT
   size_ = src.size_;
   max_size_ = src.max_size_;
-  sparse_to_dense_ = std::move(src.sparse_to_dense_);
+  sparse_ = std::move(src.sparse_);
   dense_ = std::move(src.dense_);
   // clear out the source
   src.size_ = 0;
@@ -425,10 +428,10 @@
   DebugCheckInvariants();
   if (max_size > max_size_) {
     std::unique_ptr<int[]> a(new int[max_size]);
-    if (sparse_to_dense_) {
-      std::copy_n(sparse_to_dense_.get(), max_size_, a.get());
+    if (sparse_) {
+      std::copy_n(sparse_.get(), max_size_, a.get());
     }
-    sparse_to_dense_ = std::move(a);
+    sparse_ = std::move(a);
 
     std::unique_ptr<IndexValue[]> b(new IndexValue[max_size]);
     if (dense_) {
@@ -436,12 +439,7 @@
     }
     dense_ = std::move(b);
 
-    if (ShouldInitializeMemory()) {
-      for (int i = max_size_; i < max_size; i++) {
-        sparse_to_dense_[i] = 0xababababU;
-        dense_[i].index_ = 0xababababU;
-      }
-    }
+    MaybeInitializeMemory(max_size_, max_size);
   }
   max_size_ = max_size;
   if (size_ > max_size_)
@@ -457,15 +455,15 @@
   if (static_cast<uint32_t>(i) >= static_cast<uint32_t>(max_size_)) {
     return false;
   }
-  // Unsigned comparison avoids checking sparse_to_dense_[i] < 0.
-  return (uint32_t)sparse_to_dense_[i] < (uint32_t)size_ &&
-         dense_[sparse_to_dense_[i]].index_ == i;
+  // Unsigned comparison avoids checking sparse_[i] < 0.
+  return (uint32_t)sparse_[i] < (uint32_t)size_ &&
+         dense_[sparse_[i]].index_ == i;
 }
 
 template<typename Value>
 const Value& SparseArray<Value>::get_existing(int i) const {
   assert(has_index(i));
-  return dense_[sparse_to_dense_[i]].second;
+  return dense_[sparse_[i]].second;
 }
 
 template<typename Value>
@@ -480,10 +478,10 @@
 void SparseArray<Value>::erase_existing(int i) {
   DebugCheckInvariants();
   assert(has_index(i));
-  int di = sparse_to_dense_[i];
+  int di = sparse_[i];
   if (di < size_ - 1) {
     dense_[di] = std::move(dense_[size_ - 1]);
-    sparse_to_dense_[dense_[di].index_] = di;
+    sparse_[dense_[di].index_] = di;
   }
   size_--;
   DebugCheckInvariants();
@@ -493,24 +491,17 @@
 void SparseArray<Value>::create_index(int i) {
   assert(!has_index(i));
   assert(size_ < max_size_);
-  sparse_to_dense_[i] = size_;
+  sparse_[i] = size_;
   dense_[size_].index_ = i;
   size_++;
 }
 
 template<typename Value> SparseArray<Value>::SparseArray(int max_size) {
-  max_size_ = max_size;
-  sparse_to_dense_.reset(new int[max_size]);
+  sparse_.reset(new int[max_size]);
   dense_.reset(new IndexValue[max_size]);
   size_ = 0;
-
-  if (ShouldInitializeMemory()) {
-    for (int i = 0; i < max_size; i++) {
-      sparse_to_dense_[i] = 0xababababU;
-      dense_[i].index_ = 0xababababU;
-    }
-  }
-
+  MaybeInitializeMemory(size_, max_size);
+  max_size_ = max_size;
   DebugCheckInvariants();
 }
 
@@ -521,7 +512,7 @@
 template<typename Value> void SparseArray<Value>::DebugCheckInvariants() const 
{
   assert(0 <= size_);
   assert(size_ <= max_size_);
-  assert(size_ == 0 || sparse_to_dense_ != NULL);
+  assert(size_ == 0 || sparse_ != NULL);
 }
 
 // Comparison function for sorting.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/re2-2017-11-01/util/sparse_set.h 
new/re2-2017-12-01/util/sparse_set.h
--- old/re2-2017-11-01/util/sparse_set.h        2017-10-28 04:16:51.000000000 
+0200
+++ new/re2-2017-12-01/util/sparse_set.h        2017-11-16 22:52:42.000000000 
+0100
@@ -47,9 +47,17 @@
 //
 // See sparse_array.h for implementation details.
 
+// Doing this simplifies the logic below.
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
 #include <assert.h>
 #include <stdint.h>
 #include <string.h>
+#if __has_feature(memory_sanitizer)
+#include <sanitizer/msan_interface.h>
+#endif
 #include <algorithm>
 #include <memory>
 #include <utility>
@@ -145,7 +153,7 @@
         create_index(i);
     }
     DebugCheckInvariants();
-    return dense_.get() + sparse_to_dense_[i];
+    return dense_.get() + sparse_[i];
   }
 
   // Add the index i to the set.
@@ -159,23 +167,20 @@
   // and at the beginning and end of all public non-const member functions.
   void DebugCheckInvariants() const;
 
-  static bool ShouldInitializeMemory() {
-#if defined(__has_feature)
+  // Initializes memory for elements [min, max).
+  void MaybeInitializeMemory(int min, int max) {
 #if __has_feature(memory_sanitizer)
-    return true;
-#else
-    return false;
-#endif
+    __msan_unpoison(sparse_.get() + min, (max - min) * sizeof sparse_[0]);
 #elif defined(RE2_ON_VALGRIND)
-    return true;
-#else
-    return false;
+    for (int i = min; i < max; i++) {
+      sparse_[i] = 0xababababU;
+    }
 #endif
   }
 
   int size_ = 0;
   int max_size_ = 0;
-  std::unique_ptr<int[]> sparse_to_dense_;
+  std::unique_ptr<int[]> sparse_;
   std::unique_ptr<int[]> dense_;
 };
 
@@ -189,10 +194,10 @@
   DebugCheckInvariants();
   if (max_size > max_size_) {
     std::unique_ptr<int[]> a(new int[max_size]);
-    if (sparse_to_dense_) {
-      std::copy_n(sparse_to_dense_.get(), max_size_, a.get());
+    if (sparse_) {
+      std::copy_n(sparse_.get(), max_size_, a.get());
     }
-    sparse_to_dense_ = std::move(a);
+    sparse_ = std::move(a);
 
     std::unique_ptr<int[]> b(new int[max_size]);
     if (dense_) {
@@ -200,12 +205,7 @@
     }
     dense_ = std::move(b);
 
-    if (ShouldInitializeMemory()) {
-      for (int i = max_size_; i < max_size; i++) {
-        sparse_to_dense_[i] = 0xababababU;
-        dense_[i] = 0xababababU;
-      }
-    }
+    MaybeInitializeMemory(max_size_, max_size);
   }
   max_size_ = max_size;
   if (size_ > max_size_)
@@ -221,33 +221,26 @@
   if (static_cast<uint32_t>(i) >= static_cast<uint32_t>(max_size_)) {
     return false;
   }
-  // Unsigned comparison avoids checking sparse_to_dense_[i] < 0.
-  return (uint32_t)sparse_to_dense_[i] < (uint32_t)size_ &&
-         dense_[sparse_to_dense_[i]] == i;
+  // Unsigned comparison avoids checking sparse_[i] < 0.
+  return (uint32_t)sparse_[i] < (uint32_t)size_ &&
+         dense_[sparse_[i]] == i;
 }
 
 template<typename Value>
 void SparseSetT<Value>::create_index(int i) {
   assert(!contains(i));
   assert(size_ < max_size_);
-  sparse_to_dense_[i] = size_;
+  sparse_[i] = size_;
   dense_[size_] = i;
   size_++;
 }
 
 template<typename Value> SparseSetT<Value>::SparseSetT(int max_size) {
-  max_size_ = max_size;
-  sparse_to_dense_.reset(new int[max_size]);
+  sparse_.reset(new int[max_size]);
   dense_.reset(new int[max_size]);
   size_ = 0;
-
-  if (ShouldInitializeMemory()) {
-    for (int i = 0; i < max_size; i++) {
-      sparse_to_dense_[i] = 0xababababU;
-      dense_[i] = 0xababababU;
-    }
-  }
-
+  MaybeInitializeMemory(size_, max_size);
+  max_size_ = max_size;
   DebugCheckInvariants();
 }
 
@@ -258,7 +251,7 @@
 template<typename Value> void SparseSetT<Value>::DebugCheckInvariants() const {
   assert(0 <= size_);
   assert(size_ <= max_size_);
-  assert(size_ == 0 || sparse_to_dense_ != NULL);
+  assert(size_ == 0 || sparse_ != NULL);
 }
 
 // Comparison function for sorting.


Reply via email to