aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2020-08-25 16:18:58 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2020-08-25 16:18:58 +0200
commit3cf8015a4941c43ae82100dc0d998945485d760c (patch)
tree0388fc33770bffb92fcc016bdb89487370a4ec8e
parent190af1175755e2a76b1ac182414ae261a15bb276 (diff)
Fix bug in interaction of unmatch logic with target groups
-rw-r--r--libbuild2/algorithm.cxx2
-rw-r--r--libbuild2/algorithm.ixx9
-rw-r--r--libbuild2/operation.cxx15
3 files changed, 23 insertions, 3 deletions
diff --git a/libbuild2/algorithm.cxx b/libbuild2/algorithm.cxx
index 75540ff..5b340c7 100644
--- a/libbuild2/algorithm.cxx
+++ b/libbuild2/algorithm.cxx
@@ -584,7 +584,7 @@ namespace build2
else
l.offset = target::offset_tried;
- return r; // Group state.
+ return r; // Group state (must be consistent with matched_state()).
}
try
diff --git a/libbuild2/algorithm.ixx b/libbuild2/algorithm.ixx
index 9d77d61..97a8519 100644
--- a/libbuild2/algorithm.ixx
+++ b/libbuild2/algorithm.ixx
@@ -322,12 +322,17 @@ namespace build2
if (s == target_state::failed)
throw failed ();
+ // If this is a member of the group then the state we've got is that of
+ // the group, not the member, while the member has matched the group and
+ // incremented its dependency counts. As a result, we cannot rely on the
+ // unchanged state in this case.
+ //
switch (um)
{
case unmatch::none: break;
case unmatch::unchanged:
{
- if (s == target_state::unchanged)
+ if (s == target_state::unchanged && t.group == nullptr)
return make_pair (true, s);
break;
@@ -338,7 +343,7 @@ namespace build2
// we never decrement this count during match so that someone else
// cannot change their mind).
//
- if (s == target_state::unchanged ||
+ if ((s == target_state::unchanged && t.group == nullptr) ||
t[a].dependents.load (memory_order_consume) != 0)
return make_pair (true, s);
diff --git a/libbuild2/operation.cxx b/libbuild2/operation.cxx
index a14dfb7..1594d8b 100644
--- a/libbuild2/operation.cxx
+++ b/libbuild2/operation.cxx
@@ -442,6 +442,21 @@ namespace build2
// haven't failed (in which case we could have bailed out early).
//
assert (ctx.target_count.load (memory_order_relaxed) == 0);
+
+#ifndef NDEBUG
+ if (ctx.dependency_count.load (memory_order_relaxed) != 0)
+ {
+ diag_record dr;
+ dr << info << "detected unexecuted matched targets:";
+
+ for (const auto& pt: ctx.targets)
+ {
+ const target& t (*pt);
+ if (size_t n = t[a].dependents.load (memory_order_relaxed))
+ dr << text << t << ' ' << n;
+ }
+ }
+#endif
assert (ctx.dependency_count.load (memory_order_relaxed) == 0);
}