Mark NOTREACHED as [[noreturn]] This prevents compiler errors when you write NOTREACHED but do not add a return statement. Change-Id: Ic878ba3e89e1e933a1288a3972505f736a6a6964 Reviewed-on: https://gn-review.googlesource.com/c/gn/+/25601 Reviewed-by: Takuto Ikuta <tikuta@google.com> Commit-Queue: Matt Stark <msta@google.com>
diff --git a/src/base/logging.cc b/src/base/logging.cc index e8929c1..2e1dc6e 100644 --- a/src/base/logging.cc +++ b/src/base/logging.cc
@@ -7,6 +7,7 @@ #include <limits.h> #include <stdint.h> +#include <cstdlib> #include <iterator> #include <thread> @@ -186,6 +187,26 @@ } } +NotReachedLogMessage::NotReachedLogMessage(const char* file, int line) + : log_message_(std::in_place, file, line, LOG_FATAL) {} + +// Suppress MSVC warning "destructor never returns, potential memory leak". +#if defined(COMPILER_MSVC) +#pragma warning(push) +#pragma warning(disable : 4722) +#endif +NotReachedLogMessage::~NotReachedLogMessage() { + log_message_.reset(); + IMMEDIATE_CRASH(); +} +#if defined(COMPILER_MSVC) +#pragma warning(pop) +#endif + +std::ostream& NotReachedLogMessage::stream() { + return log_message_->stream(); +} + // writes the common header info to the stream void LogMessage::Init(const char* file, int line) { std::string_view filename(file);
diff --git a/src/base/logging.h b/src/base/logging.h index a5b3e55..e08d386 100644 --- a/src/base/logging.h +++ b/src/base/logging.h
@@ -9,6 +9,7 @@ #include <cassert> #include <cstring> +#include <optional> #include <sstream> #include <string> #include <string_view> @@ -729,8 +730,6 @@ #define DCHECK_GE(val1, val2) DCHECK_OP(GE, >=, val1, val2) #define DCHECK_GT(val1, val2) DCHECK_OP(GT, >, val1, val2) -#define NOTREACHED() DCHECK(false) - // Redefine the standard assert to use our nice log files #undef assert #define assert(x) DLOG_ASSERT(x) @@ -800,6 +799,20 @@ LogMessage& operator=(const LogMessage&) = delete; }; +class NotReachedLogMessage { + public: + NotReachedLogMessage(const char* file, int line); + [[noreturn]] ~NotReachedLogMessage(); + + std::ostream& stream(); + + private: + std::optional<LogMessage> log_message_; + + NotReachedLogMessage(const NotReachedLogMessage&) = delete; + NotReachedLogMessage& operator=(const NotReachedLogMessage&) = delete; +}; + // This class is used to explicitly ignore values in the conditional // logging macros. This avoids compiler warnings like "value computed // is not used" and "statement has no effect". @@ -811,6 +824,10 @@ void operator&(std::ostream&) {} }; +#define NOTREACHED() \ + ::logging::LogMessageVoidify() & \ + ::logging::NotReachedLogMessage(__FILE__, __LINE__).stream() + #if defined(OS_WIN) typedef unsigned long SystemErrorCode; #elif defined(OS_POSIX) || defined(OS_FUCHSIA)