diff options
author | Nico Weber <nicolasweber@gmx.de> | 2015-03-15 23:34:03 (GMT) |
---|---|---|
committer | Nico Weber <nicolasweber@gmx.de> | 2015-03-15 23:34:03 (GMT) |
commit | 56e9d08c028d2c16f787041dc1f41271464a8bdc (patch) | |
tree | 7c666efb09121fba46787e3bd3b47bf28ddeb5f2 /src/manifest_parser_test.cc | |
parent | 51f06facf46e7a1a5338a4ca2ec9b8441c44c405 (diff) | |
download | Ninja-56e9d08c028d2c16f787041dc1f41271464a8bdc.zip Ninja-56e9d08c028d2c16f787041dc1f41271464a8bdc.tar.gz Ninja-56e9d08c028d2c16f787041dc1f41271464a8bdc.tar.bz2 |
Build self-consistent graphs for dupe edges with multiple outputs.
Fixes #867, both the crashes and "[stuck]" issues.
The problem was that a duplicate edge would modify the in_edge of the
outputs of the new build rule, but the edge corresponding to the old
build rule would still think that the in_edge points to itself.
`old_edge->outputs_[0]->in_edge()` would not return `old_edge`, which
confused the scan logic.
As fix, let `State::AddOut()` reject changing in_edge if it's already
set. This changes behavior in a minor way: Previously, if there were
multiple edges for a single output, the last edge would be kept. Now,
the first edge is kept. This only had mostly-well-defined semantics if
all duplicate edges are the same (which is the only case I've seen in
practice), and for that case the behavior doesn't change.
For testing, add a VerifyGraph() function and call that every time any
test graph is parsed. That's a bit more code than just copying the test
cases from the bug into build_test.cc, but it also yields better test
coverage overall.
Diffstat (limited to 'src/manifest_parser_test.cc')
-rw-r--r-- | src/manifest_parser_test.cc | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/src/manifest_parser_test.cc b/src/manifest_parser_test.cc index e13d728..7e38fc6 100644 --- a/src/manifest_parser_test.cc +++ b/src/manifest_parser_test.cc @@ -28,6 +28,7 @@ struct ParserTest : public testing::Test, string err; EXPECT_TRUE(parser.ParseTest(input, &err)); ASSERT_EQ("", err); + VerifyGraph(state); } virtual bool ReadFile(const string& path, string* content, string* err) { @@ -340,6 +341,18 @@ TEST_F(ParserTest, CanonicalizePathsBackslashes) { } #endif +TEST_F(ParserTest, DuplicateEdgeWithMultipleOutputs) { + ASSERT_NO_FATAL_FAILURE(AssertParse( +"rule cat\n" +" command = cat $in > $out\n" +"build out1 out2: cat in1\n" +"build out1: cat in2\n" +"build final: cat out1\n" +)); + // AssertParse() checks that the generated build graph is self-consistent. + // That's all the checking that this test needs. +} + TEST_F(ParserTest, ReservedWords) { ASSERT_NO_FATAL_FAILURE(AssertParse( "rule build\n" |