]> git.ipfire.org Git - thirdparty/vectorscan.git/commitdiff
ng: ensure that only match states have reports
authorJustin Viiret <justin.viiret@intel.com>
Mon, 18 Jul 2016 02:41:31 +0000 (12:41 +1000)
committerMatthew Barr <matthew.barr@intel.com>
Wed, 10 Aug 2016 05:05:23 +0000 (15:05 +1000)
Ensure (and assert) that vertices without an edge to {accept, acceptEod}
do not have reports set.

src/nfagraph/ng.cpp
src/nfagraph/ng_asserts.cpp
src/nfagraph/ng_calc_components.cpp
src/nfagraph/ng_limex.cpp
src/nfagraph/ng_rose.cpp
src/nfagraph/ng_util.cpp
src/nfagraph/ng_util.h
unit/internal/lbr.cpp
unit/internal/limex_nfa.cpp
unit/internal/nfagraph_repeat.cpp

index 35b2eb351833145169a1925c6583dd4c7ac55921..deca3fd5cd0cabed9e32df4a580a474396d69bf4 100644 (file)
@@ -105,6 +105,7 @@ bool addComponentSom(NG &ng, NGHolder &g, const NGWrapper &w,
     DEBUG_PRINTF("doing som\n");
     dumpComponent(g, "03_presom", w.expressionIndex, comp_id, ng.cc.grey);
     assert(hasCorrectlyNumberedVertices(g));
+    assert(allMatchStatesHaveReports(w));
 
     // First, we try the "SOM chain" support in ng_som.cpp.
 
@@ -208,6 +209,8 @@ bool addComponent(NG &ng, NGHolder &g, const NGWrapper &w, const som_type som,
 
     dumpComponent(g, "01_begin", w.expressionIndex, comp_id, ng.cc.grey);
 
+    assert(allMatchStatesHaveReports(w));
+
     reduceGraph(g, som, w.utf8, cc);
 
     dumpComponent(g, "02_reduced", w.expressionIndex, comp_id, ng.cc.grey);
@@ -232,6 +235,8 @@ bool addComponent(NG &ng, NGHolder &g, const NGWrapper &w, const som_type som,
         }
     }
 
+    assert(allMatchStatesHaveReports(w));
+
     if (splitOffAnchoredAcyclic(*ng.rose, g, cc)) {
         return true;
     }
index 2d02751fb61f5aba3d0e8a87726a2e0f3179c7fd..e9e3934507ddca46f70538aa661baf6b3f94b1cc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Intel Corporation
+ * Copyright (c) 2015-2016, Intel Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -553,6 +553,7 @@ void ensureCodePointStart(ReportManager &rm, NGWrapper &g) {
         add_edge(g.startDs, v_4, g);
         remove_edge(orig, g);
         g.renumberEdges();
+        clearReports(g);
     }
 }
 
index 9365cfb376e65af0631061b0394c73d7c07c2d3b..658e700135f6417c0b0a9500ba918d43685e3fcd 100644 (file)
@@ -363,6 +363,12 @@ void splitIntoComponents(const NGHolder &g, deque<unique_ptr<NGHolder>> &comps,
         *shell_comp = true;
     }
 
+    // Ensure that only vertices with accept edges have reports.
+    for (auto &gc : comps) {
+        assert(gc);
+        clearReports(*gc);
+    }
+
     // We should never produce empty component graphs.
     assert(all_of(begin(comps), end(comps),
                   [](const unique_ptr<NGHolder> &g_comp) {
index a82d18b6e90661672d6e7b2fb743c9e19111c47e..a8a5113d62b5ea78d6d1ba3472d0a5eb4cab5b7e 100644 (file)
@@ -79,13 +79,17 @@ bool sanityCheckGraph(const NGHolder &g,
             }
         }
 
-        // Vertices with edges to accept or acceptEod must have reports.
+        // Vertices with edges to accept or acceptEod must have reports and
+        // other vertices must not have them.
         if (is_match_vertex(v, g) && v != g.accept) {
             if (g[v].reports.empty()) {
-                DEBUG_PRINTF("vertex %u has no reports\n",
-                             g[v].index);
+                DEBUG_PRINTF("vertex %u has no reports\n", g[v].index);
                 return false;
             }
+        } else if (!g[v].reports.empty()) {
+            DEBUG_PRINTF("vertex %u has reports but no accept edge\n",
+                         g[v].index);
+            return false;
         }
 
         // Participant vertices should have distinct state indices.
index 4b16364ae6cd6278637b8a3bf9ec5dee65b500b4..aba4a7c35fceafaa3927c7c9fbe14a94a354e857 100644 (file)
@@ -872,6 +872,7 @@ u32 removeTrailingLiteralStates(NGHolder &g, const ue2_literal &lit,
     }
 
     clear_in_edges(g.accept, g);
+    clearReports(g);
 
     vector<NFAVertex> verts(pred.begin(), pred.end());
     sort(verts.begin(), verts.end(), VertexIndexOrdering<NGHolder>(g));
index e9f6be55ebcd4b55ff88f996312918ffa15e7b86..c629d553ba4480cf69ebf87117f64d14dea5c4ae 100644 (file)
@@ -631,16 +631,18 @@ unique_ptr<NGHolder> cloneHolder(const NGHolder &in) {
 }
 
 #ifndef NDEBUG
-/** \brief Used in sanity-checking assertions: returns true if all vertices
- * leading to accept or acceptEod have at least one report ID. */
+
 bool allMatchStatesHaveReports(const NGHolder &g) {
+    unordered_set<NFAVertex> reporters;
     for (auto v : inv_adjacent_vertices_range(g.accept, g)) {
         if (g[v].reports.empty()) {
             DEBUG_PRINTF("vertex %u has no reports!\n",
                          g[v].index);
             return false;
         }
+        reporters.insert(v);
     }
+
     for (auto v : inv_adjacent_vertices_range(g.acceptEod, g)) {
         if (v == g.accept) {
             continue; // stylised edge
@@ -650,12 +652,20 @@ bool allMatchStatesHaveReports(const NGHolder &g) {
                          g[v].index);
             return false;
         }
+        reporters.insert(v);
     }
+
+    for (auto v : vertices_range(g)) {
+        if (!contains(reporters, v) && !g[v].reports.empty()) {
+            DEBUG_PRINTF("vertex %u is not a match state, but has reports!\n",
+                         g[v].index);
+            return false;
+        }
+    }
+
     return true;
 }
 
-/** Assertion: returns true if the vertices in this graph are contiguously (and
- * uniquely) numbered from zero. */
 bool hasCorrectlyNumberedVertices(const NGHolder &g) {
     size_t count = num_vertices(g);
     vector<bool> ids(count, false);
@@ -670,8 +680,6 @@ bool hasCorrectlyNumberedVertices(const NGHolder &g) {
         && num_vertices(g) == num_vertices(g.g);
 }
 
-/** Assertion: returns true if the edges in this graph are contiguously (and
- * uniquely) numbered from zero. */
 bool hasCorrectlyNumberedEdges(const NGHolder &g) {
     size_t count = num_edges(g);
     vector<bool> ids(count, false);
index 833523c75d41d64aba9bd8c6d52dbfa994f8e6df..4f58dc455281fdf3a8f94f9515cfdcf17a286756 100644 (file)
@@ -297,15 +297,29 @@ void clearReports(NGHolder &g);
 void duplicateReport(NGHolder &g, ReportID r_old, ReportID r_new);
 
 #ifndef NDEBUG
-// Assertions: only available in internal builds
 
-/** \brief Used in sanity-checking assertions: returns true if all vertices
- * leading to accept or acceptEod have at least one report ID. */
+// Assertions: only available in internal builds.
+
+/**
+ * Used in sanity-checking assertions: returns true if all vertices
+ * with edges to accept or acceptEod have at least one report ID. Additionally,
+ * checks that ONLY vertices with edges to accept or acceptEod has reports.
+ */
 bool allMatchStatesHaveReports(const NGHolder &g);
 
+/**
+ * Assertion: returns true if the vertices in this graph are contiguously (and
+ * uniquely) numbered from zero.
+ */
 bool hasCorrectlyNumberedVertices(const NGHolder &g);
+
+/**
+ * Assertion: returns true if the edges in this graph are contiguously (and
+ * uniquely) numbered from zero.
+ */
 bool hasCorrectlyNumberedEdges(const NGHolder &g);
-#endif
+
+#endif // NDEBUG
 
 } // namespace ue2
 
index bd799c0fbe27881f675beb285c31672c4a2f5f6b..e40bda02dc1727f2c1a2eae38ec6b95469ca8376 100644 (file)
@@ -36,6 +36,7 @@
 #include "nfa/nfa_internal.h"
 #include "nfa/nfa_api_util.h"
 #include "nfagraph/ng_lbr.h"
+#include "nfagraph/ng_util.h"
 #include "util/alloc.h"
 #include "util/compile_context.h"
 #include "grey.h"
@@ -97,6 +98,7 @@ protected:
         ParsedExpression parsed(0, pattern.c_str(), flags, 0);
         unique_ptr<NGWrapper> g = buildWrapper(rm, cc, parsed);
         ASSERT_TRUE(g != nullptr);
+        clearReports(*g);
 
         ASSERT_TRUE(isLBR(*g, grey));
 
index 926bf6eb2cb4f268dde8418cc597bdd3eb2beae0..6bb4fcb9d10852af0feaf055b7411bd2c04d7354 100644 (file)
 
 #include "grey.h"
 #include "compiler/compiler.h"
-#include "nfagraph/ng.h"
-#include "nfagraph/ng_limex.h"
-#include "nfagraph/ng_restructuring.h"
 #include "nfa/limex_context.h"
 #include "nfa/limex_internal.h"
 #include "nfa/nfa_api.h"
 #include "nfa/nfa_api_util.h"
 #include "nfa/nfa_internal.h"
+#include "nfagraph/ng.h"
+#include "nfagraph/ng_limex.h"
+#include "nfagraph/ng_restructuring.h"
+#include "nfagraph/ng_util.h"
 #include "util/alloc.h"
 #include "util/target_info.h"
 
@@ -76,6 +77,7 @@ protected:
         ParsedExpression parsed(0, expr.c_str(), flags, 0);
         unique_ptr<NGWrapper> g = buildWrapper(rm, cc, parsed);
         ASSERT_TRUE(g != nullptr);
+        clearReports(*g);
 
         rm.setProgramOffset(0, MATCH_REPORT);
 
@@ -310,10 +312,12 @@ protected:
         ParsedExpression parsed(0, expr.c_str(), flags, 0);
         unique_ptr<NGWrapper> g = buildWrapper(rm, cc, parsed);
         ASSERT_TRUE(g != nullptr);
+        clearReports(*g);
 
         // Reverse the graph and add some reports on the accept vertices.
         NGHolder g_rev(NFA_REV_PREFIX);
         reverseHolder(*g, g_rev);
+        clearReports(g_rev);
         for (NFAVertex v : inv_adjacent_vertices_range(g_rev.accept, g_rev)) {
             g_rev[v].reports.insert(0);
         }
@@ -367,6 +371,7 @@ protected:
         ReportManager rm(cc.grey);
         unique_ptr<NGWrapper> g = buildWrapper(rm, cc, parsed);
         ASSERT_TRUE(g != nullptr);
+        clearReports(*g);
 
         rm.setProgramOffset(0, MATCH_REPORT);
 
index 2473d75565e76c8f57092c496d28975c308d3914..b34d12717fc83c0d57839a2ed54a78fd3847f36e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Intel Corporation
+ * Copyright (c) 2015-2016, Intel Corporation
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -32,6 +32,7 @@
 
 #include "gtest/gtest.h"
 #include "nfagraph/ng_repeat.h"
+#include "nfagraph/ng_util.h"
 #include "util/depth.h"
 #include "hs_compile.h"
 
@@ -89,12 +90,15 @@ static const PureRepeatTest pureRepeatTests[] = {
     { "^..?..?..?..?..?", 5, 10 }
 };
 
-INSTANTIATE_TEST_CASE_P(PureRepeat, NFAPureRepeatTest, ValuesIn(pureRepeatTests));
+INSTANTIATE_TEST_CASE_P(PureRepeat, NFAPureRepeatTest,
+                        ValuesIn(pureRepeatTests));
 
 TEST_P(NFAPureRepeatTest, Check) {
     const PureRepeatTest &t = GetParam();
     SCOPED_TRACE(testing::Message() << "Pattern: " << t.pattern);
-    unique_ptr<NGWrapper> w(constructGraph(t.pattern, HS_FLAG_ALLOWEMPTY));
+    auto w = constructGraph(t.pattern, HS_FLAG_ALLOWEMPTY);
+    ASSERT_TRUE(w != nullptr);
+    clearReports(*w);
 
     PureRepeat repeat;
     bool result = isPureRepeat(*w, repeat);