From 4825ef40953aeb4a71e3625203b760381da6b0d7 Mon Sep 17 00:00:00 2001 From: Abseil Team Date: Thu, 23 Feb 2023 13:05:39 -0800 Subject: Initialize ScopedMockLog.is_triggered_ with false. In C++20, this happens by default, but in C++17, it's left uninitialized if no logs are sent and StartCapturingLogs is never called. The destructor then makes an attempt to access it, which is both unsafe and not very useful while it is uninitialized. Also add a test that expects the appropriate CHECK fail when StartCapturingLogs is not called. PiperOrigin-RevId: 511865440 Change-Id: Ie23ff3f901e926761d5f487e10d33c21c3bd43d3 --- absl/log/scoped_mock_log.cc | 2 +- absl/log/scoped_mock_log.h | 3 +++ absl/log/scoped_mock_log_test.cc | 5 +++++ 3 files changed, 9 insertions(+), 1 deletion(-) (limited to 'absl/log') diff --git a/absl/log/scoped_mock_log.cc b/absl/log/scoped_mock_log.cc index 4ebc0a9f..39a0a52a 100644 --- a/absl/log/scoped_mock_log.cc +++ b/absl/log/scoped_mock_log.cc @@ -30,7 +30,7 @@ namespace absl { ABSL_NAMESPACE_BEGIN ScopedMockLog::ScopedMockLog(MockLogDefault default_exp) - : sink_(this), is_capturing_logs_(false) { + : sink_(this), is_capturing_logs_(false), is_triggered_(false) { if (default_exp == MockLogDefault::kIgnoreUnexpected) { // Ignore all calls to Log we did not set expectations for. EXPECT_CALL(*this, Log).Times(::testing::AnyNumber()); diff --git a/absl/log/scoped_mock_log.h b/absl/log/scoped_mock_log.h index 44470c16..399e604d 100644 --- a/absl/log/scoped_mock_log.h +++ b/absl/log/scoped_mock_log.h @@ -185,6 +185,9 @@ class ScopedMockLog final { ForwardingSink sink_; bool is_capturing_logs_; + // Until C++20, the default constructor leaves the underlying value wrapped in + // std::atomic uninitialized, so all constructors should be sure to initialize + // is_triggered_. std::atomic is_triggered_; }; diff --git a/absl/log/scoped_mock_log_test.cc b/absl/log/scoped_mock_log_test.cc index 44b8d737..42736939 100644 --- a/absl/log/scoped_mock_log_test.cc +++ b/absl/log/scoped_mock_log_test.cc @@ -71,6 +71,11 @@ TEST(ScopedMockLogDeathTest, StopCapturingLogsCannotBeCalledWhenNotCapturing) { }, "StopCapturingLogs"); } + +TEST(ScopedMockLogDeathTest, FailsCheckIfStartCapturingLogsIsNeverCalled) { + EXPECT_DEATH({ absl::ScopedMockLog log; }, + "Did you forget to call StartCapturingLogs"); +} #endif // Tests that ScopedMockLog intercepts LOG()s when it's alive. -- cgit v1.2.3