summaryrefslogtreecommitdiffstats
path: root/src/manifest_parser.cc
diff options
context:
space:
mode:
authorNico Weber <nicolasweber@gmx.de>2015-03-19 23:42:06 (GMT)
committerNico Weber <nicolasweber@gmx.de>2015-03-19 23:42:06 (GMT)
commitf5c5789aad8001e15a7e4f1ee0dee0c2b688e993 (patch)
tree9e26b5bbf6486a710eba81c0d0214b2fb3f3e348 /src/manifest_parser.cc
parent20a840539ce87a343b414f52a3330706a731b044 (diff)
downloadNinja-f5c5789aad8001e15a7e4f1ee0dee0c2b688e993.zip
Ninja-f5c5789aad8001e15a7e4f1ee0dee0c2b688e993.tar.gz
Ninja-f5c5789aad8001e15a7e4f1ee0dee0c2b688e993.tar.bz2
Another crash fix for duplicate edges. Fixes #939.
Patch #933 fixed a crash with duplicate edges by not adding edges to the graph if all the edge's outputs are already built by other edges. However, it added the edge to the out_edges of the edge's input nodes before deleting it, letting inputs refer to dead edges. To fix, move the check for deleting an edge above the code that adds inputs. Expand VerifyGraph() to check that nodes don't refer to edges that aren't present in the state.
Diffstat (limited to 'src/manifest_parser.cc')
-rw-r--r--src/manifest_parser.cc24
1 files changed, 12 insertions, 12 deletions
diff --git a/src/manifest_parser.cc b/src/manifest_parser.cc
index f0457dd..4e639d1 100644
--- a/src/manifest_parser.cc
+++ b/src/manifest_parser.cc
@@ -321,14 +321,6 @@ bool ManifestParser::ParseEdge(string* err) {
edge->pool_ = pool;
}
- for (vector<EvalString>::iterator i = ins.begin(); i != ins.end(); ++i) {
- string path = i->Evaluate(env);
- string path_err;
- unsigned int slash_bits;
- if (!CanonicalizePath(&path, &slash_bits, &path_err))
- return lexer_.Error(path_err, err);
- state_->AddIn(edge, path, slash_bits);
- }
for (vector<EvalString>::iterator i = outs.begin(); i != outs.end(); ++i) {
string path = i->Evaluate(env);
string path_err;
@@ -337,17 +329,25 @@ bool ManifestParser::ParseEdge(string* err) {
return lexer_.Error(path_err, err);
state_->AddOut(edge, path, slash_bits);
}
- edge->implicit_deps_ = implicit;
- edge->order_only_deps_ = order_only;
-
if (edge->outputs_.empty()) {
// All outputs of the edge are already created by other edges. Don't add
- // this edge.
+ // this edge. Do this check before input nodes are connected to the edge.
state_->edges_.pop_back();
delete edge;
return true;
}
+ for (vector<EvalString>::iterator i = ins.begin(); i != ins.end(); ++i) {
+ string path = i->Evaluate(env);
+ string path_err;
+ unsigned int slash_bits;
+ if (!CanonicalizePath(&path, &slash_bits, &path_err))
+ return lexer_.Error(path_err, err);
+ state_->AddIn(edge, path, slash_bits);
+ }
+ edge->implicit_deps_ = implicit;
+ edge->order_only_deps_ = order_only;
+
// Multiple outputs aren't (yet?) supported with depslog.
string deps_type = edge->GetBinding("deps");
if (!deps_type.empty() && edge->outputs_.size() > 1) {