[gn] Use DCHECK in Target::info() Follow-up to https://gn-review.googlesource.com/c/gn/+/26480. As pointed out by Matt Stark (msta@), having a lazy 'info_.emplace(this)' fallback inside Target::info() could theoretically allow concurrent mutation if info() were ever called on an unresolved target in a multi-threaded context. In production, Target::OnResolvedWithoutChecks() is always called before any multi-threaded queries occur. Across the entire unit test suite (845 tests), only a single test (NinjaCBinaryTargetWriterTest. DupeObjFileError) invoked NinjaCBinaryTargetWriter without calling OnResolved() first. By adding 'ASSERT_TRUE(target.OnResolved(&err))' to DupeObjFileError, we can replace the lazy initialization in Target::info() with 'DCHECK(info_.has_value())', making info() strictly read-only and branchless in release builds. Note: 'info_' itself remains 'mutable' because ResolvedTargetData queries receive 'const Target*' and lazily compute/populate the cache fields inside TargetInfo (e.g., lib_dirs, inherited_libs). Keeping 'mutable' on 'info_' as a whole avoids scattering 'mutable' across ~20 individual fields inside TargetInfo and modifying all helper signatures. TAG=agy CONV=4cb5d931-60a8-4f44-8632-3e8d9fb10a8d Change-Id: I6a697e0172473d38b80ca04ea0985c6dab8e3d44 Reviewed-on: https://gn-review.googlesource.com/c/gn/+/26500 Commit-Queue: Takuto Ikuta <tikuta@google.com> Reviewed-by: Matt Stark <msta@google.com>
diff --git a/src/gn/ninja_c_binary_target_writer_unittest.cc b/src/gn/ninja_c_binary_target_writer_unittest.cc index 34a473f..2f4977d 100644 --- a/src/gn/ninja_c_binary_target_writer_unittest.cc +++ b/src/gn/ninja_c_binary_target_writer_unittest.cc
@@ -1608,10 +1608,12 @@ // This is dependent on the toolchain's object file mapping. TEST_F(NinjaCBinaryTargetWriterTest, DupeObjFileError) { TestWithScope setup; + Err err; TestTarget target(setup, "//foo:bar", Target::EXECUTABLE); target.sources().push_back(SourceFile("//a.cc")); target.sources().push_back(SourceFile("//a.cc")); target.source_types_used().Set(SourceFile::SOURCE_CPP); + ASSERT_TRUE(target.OnResolved(&err)); EXPECT_FALSE(scheduler().is_failed());
diff --git a/src/gn/target.h b/src/gn/target.h index 17995f7..17e96d4 100644 --- a/src/gn/target.h +++ b/src/gn/target.h
@@ -706,9 +706,7 @@ }; TargetInfo& info() const { - if (!info_.has_value()) { - info_.emplace(this); - } + DCHECK(info_.has_value()); return *info_; }