#include "TemporaryFile.hpp"
#include "Util.hpp"
+#include "assertions.hpp"
#include "exceptions.hpp"
AtomicFile::AtomicFile(const std::string& path, Mode mode) : m_path(path)
void
AtomicFile::commit()
{
- assert(m_stream);
+ ASSERT(m_stream);
int result = fclose(m_stream);
m_stream = nullptr;
if (result == EOF) {
ZstdCompressor.cpp
ZstdDecompressor.cpp
argprocessing.cpp
+ assertions.cpp
ccache.cpp
cleanup.cpp
compopt.cpp
#include "Config.hpp"
#include "Context.hpp"
+#include "assertions.hpp"
#include "exceptions.hpp"
namespace Compression {
return "zstd";
}
- assert(false);
- return {};
+ ASSERT(false);
}
} // namespace Compression
-// Copyright (C) 2019 Joel Rosdahl and other contributors
+// Copyright (C) 2019-2020 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
#include "NullCompressor.hpp"
#include "StdMakeUnique.hpp"
#include "ZstdCompressor.hpp"
+#include "assertions.hpp"
std::unique_ptr<Compressor>
Compressor::create_from_type(Compression::Type type,
return std::make_unique<ZstdCompressor>(stream, compression_level);
}
- assert(false);
- return {};
+ ASSERT(false);
}
#include "AtomicFile.hpp"
#include "Compression.hpp"
#include "Util.hpp"
+#include "assertions.hpp"
#include "ccache.hpp"
#include "exceptions.hpp"
return format_umask(m_umask);
}
- assert(false);
- return {}; // Never reached
+ ASSERT(false); // Never reached
}
void
#include "Counters.hpp"
#include "Statistics.hpp"
+#include "assertions.hpp"
#include <algorithm>
Counters::get(Statistic statistic) const
{
const auto index = static_cast<size_t>(statistic);
- assert(index < static_cast<size_t>(Statistic::END));
+ ASSERT(index < static_cast<size_t>(Statistic::END));
return index < m_counters.size() ? m_counters[index] : 0;
}
Counters::set(Statistic statistic, uint64_t value)
{
const auto index = static_cast<size_t>(statistic);
- assert(index < static_cast<size_t>(Statistic::END));
+ ASSERT(index < static_cast<size_t>(Statistic::END));
m_counters[index] = value;
}
uint64_t
Counters::get_raw(size_t index) const
{
- assert(index < size());
+ ASSERT(index < size());
return m_counters[index];
}
-// Copyright (C) 2019 Joel Rosdahl and other contributors
+// Copyright (C) 2019-2020 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
#include "NullDecompressor.hpp"
#include "StdMakeUnique.hpp"
#include "ZstdDecompressor.hpp"
+#include "assertions.hpp"
std::unique_ptr<Decompressor>
Decompressor::create_from_type(Compression::Type type, FILE* stream)
return std::make_unique<ZstdDecompressor>(stream);
}
- assert(false);
- return {};
+ ASSERT(false);
}
#include "system.hpp"
#include "NonCopyable.hpp"
+#include "assertions.hpp"
class Fd : NonCopyable
{
Fd::operator*() const
// clang-format on
{
- assert(m_fd != -1);
+ ASSERT(m_fd != -1);
return m_fd;
}
remain -= n;
}
} else {
- assert(marker == k_raw_file_marker);
+ ASSERT(marker == k_raw_file_marker);
auto raw_path = get_raw_file_path(m_result_path, entry_number);
auto st = Stat::stat(raw_path, Stat::OnError::throw_error);
void
ResultExtractor::on_entry_data(const uint8_t* data, size_t size)
{
- assert(m_dest_fd);
+ ASSERT(m_dest_fd);
try {
Util::write_fd(*m_dest_fd, data, size);
void
ResultRetriever::on_entry_data(const uint8_t* data, size_t size)
{
- assert((m_dest_file_type == FileType::stderr_output && !m_dest_fd)
+ ASSERT((m_dest_file_type == FileType::stderr_output && !m_dest_fd)
|| (m_dest_file_type != FileType::stderr_output && m_dest_fd));
if (m_dest_file_type == FileType::stderr_output
#include "SignalHandler.hpp"
+#include "assertions.hpp"
+
#ifndef _WIN32
# include "Context.hpp"
SignalHandler::SignalHandler(Context& ctx) : m_ctx(ctx)
{
- assert(!g_the_signal_handler);
+ ASSERT(!g_the_signal_handler);
g_the_signal_handler = this;
sigemptyset(&g_fatal_signal_set);
SignalHandler::~SignalHandler()
{
- assert(g_the_signal_handler);
+ ASSERT(g_the_signal_handler);
g_the_signal_handler = nullptr;
}
void
SignalHandler::on_signal(int signum)
{
- assert(g_the_signal_handler);
+ ASSERT(g_the_signal_handler);
Context& ctx = g_the_signal_handler->m_ctx;
// Unregister handler for this signal so that we can send the signal to
std::vector<T>
split_at(string_view input, const char* separators)
{
- assert(separators != nullptr && separators[0] != '\0');
+ ASSERT(separators != nullptr && separators[0] != '\0');
std::vector<T> result;
return 0;
}
- assert(dir[0] == '/');
- assert(path[0] == '/');
+ ASSERT(dir[0] == '/');
+ ASSERT(path[0] == '/');
const size_t limit = std::min(dir.length(), path.length());
size_t i = 0;
std::string
get_relative_path(string_view dir, string_view path)
{
- assert(Util::is_absolute_path(dir));
- assert(Util::is_absolute_path(path));
+ ASSERT(Util::is_absolute_path(dir));
+ ASSERT(Util::is_absolute_path(path));
#ifdef _WIN32
// Paths can be escaped by a slash for use with e.g. -isystem.
std::string
get_path_in_cache(string_view cache_dir, uint8_t level, string_view name)
{
- assert(level >= 1 && level <= 8);
- assert(name.length() >= level);
+ ASSERT(level >= 1 && level <= 8);
+ ASSERT(name.length() >= level);
std::string path(cache_dir);
path.reserve(path.size() + level * 2 + 1 + name.length() - level);
#include "ZstdCompressor.hpp"
#include "Logging.hpp"
+#include "assertions.hpp"
#include "exceptions.hpp"
#include <algorithm>
m_zstd_out.size = sizeof(buffer);
m_zstd_out.pos = 0;
ret = ZSTD_compressStream(m_zstd_stream, &m_zstd_out, &m_zstd_in);
- assert(!(ZSTD_isError(ret)));
+ ASSERT(!(ZSTD_isError(ret)));
size_t compressed_bytes = m_zstd_out.pos;
if (fwrite(buffer, 1, compressed_bytes, m_stream) != compressed_bytes
|| ferror(m_stream)) {
-// Copyright (C) 2019 Joel Rosdahl and other contributors
+// Copyright (C) 2019-2020 Joel Rosdahl and other contributors
//
// See doc/AUTHORS.adoc for a complete list of contributors.
//
#include "ZstdDecompressor.hpp"
+#include "assertions.hpp"
#include "exceptions.hpp"
ZstdDecompressor::ZstdDecompressor(FILE* stream)
{
size_t bytes_read = 0;
while (bytes_read < count) {
- assert(m_input_size >= m_input_consumed);
+ ASSERT(m_input_size >= m_input_consumed);
if (m_input_size == m_input_consumed) {
m_input_size = fread(m_input_buffer, 1, sizeof(m_input_buffer), m_stream);
if (m_input_size == 0) {
#include "Context.hpp"
#include "FormatNonstdStringView.hpp"
#include "Logging.hpp"
+#include "assertions.hpp"
#include "compopt.hpp"
#include "language.hpp"
bool is_cc1_option,
bool* found_pch)
{
- assert(found_pch);
+ ASSERT(found_pch);
// Try to be smart about detecting precompiled headers.
// If the option is an option for Clang (is_cc1_option), don't accept
ProcessArgsResult
process_args(Context& ctx)
{
- assert(!ctx.orig_args.empty());
+ ASSERT(!ctx.orig_args.empty());
ArgsInfo& args_info = ctx.args_info;
Config& config = ctx.config;
--- /dev/null
+// Copyright (C) 2020 Joel Rosdahl and other contributors
+//
+// See doc/AUTHORS.adoc for a complete list of contributors.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc., 51
+// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+#include "assertions.hpp"
+
+#include "Util.hpp"
+
+#include "third_party/fmt/core.h"
+
+void
+handle_failed_assertion(const char* file,
+ size_t line,
+ const char* function,
+ const char* condition)
+{
+ fmt::print(stderr,
+ "ccache: {}:{}: {}: failed assertion: {}\n",
+ Util::base_name(file),
+ line,
+ function,
+ condition);
+ abort();
+}
--- /dev/null
+// Copyright (C) 2020 Joel Rosdahl and other contributors
+//
+// See doc/AUTHORS.adoc for a complete list of contributors.
+//
+// This program is free software; you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation; either version 3 of the License, or (at your option)
+// any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program; if not, write to the Free Software Foundation, Inc., 51
+// Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+#pragma once
+
+#include "system.hpp"
+
+#ifdef _MSC_VER
+# define CCACHE_FUNCTION __func__
+#else
+# define CCACHE_FUNCTION __PRETTY_FUNCTION__
+#endif
+
+// ASSERT is like the standard C `assert` macro but enabled in both debug and
+// release builds.
+#define ASSERT(condition) \
+ do { \
+ if (!(condition)) { \
+ handle_failed_assertion( \
+ __FILE__, __LINE__, CCACHE_FUNCTION, #condition); \
+ } \
+ } while (false)
+
+// DEBUG_ASSERT is like the standard C `assert` macro, i.e. only enabled in
+// debug builds.
+#ifdef NDEBUG
+# define DEBUG_ASSERT(condition) ((void)0)
+#else
+# define DEBUG_ASSERT(condition) ASSERT(condition)
+#endif
+
+[[noreturn]] void handle_failed_assertion(const char* file,
+ size_t line,
+ const char* function,
+ const char* condition);
}
if (ctx.config.depend_mode()) {
- assert(depend_mode_hash);
+ ASSERT(depend_mode_hash);
auto result_name = result_name_from_depfile(ctx, *depend_mode_hash);
if (!result_name) {
throw Failure(Statistic::internal_error);
// -fprofile-dir=.
if (ctx.args_info.profile_generate) {
- assert(!ctx.args_info.profile_path.empty());
+ ASSERT(!ctx.args_info.profile_path.empty());
log("Adding profile directory {} to our hash", ctx.args_info.profile_path);
hash.hash_delimiter("-fprofile-dir");
hash.hash(ctx.args_info.profile_path);
umask(*ctx.original_umask);
}
- assert(!ctx.orig_args.empty());
+ ASSERT(!ctx.orig_args.empty());
ctx.orig_args.erase_with_prefix("--ccache-");
add_prefix(ctx, ctx.orig_args, ctx.config.prefix_command());
// calculate_result_name does not return nullopt if the last (direct_mode)
// argument is false.
- assert(result_name);
+ ASSERT(result_name);
ctx.set_result_name(*result_name);
if (result_name_from_manifest && result_name_from_manifest != result_name) {
#include "StdMakeUnique.hpp"
#include "ThreadPool.hpp"
#include "ZstdCompressor.hpp"
+#include "assertions.hpp"
#include "third_party/fmt/core.h"
stream, Manifest::k_magic, Manifest::k_version);
case CacheFile::Type::unknown:
- assert(false); // Handled at function entry.
- return {};
+ ASSERT(false); // Handled at function entry.
}
- assert(false);
- return {};
+ ASSERT(false);
}
std::unique_ptr<CacheEntryWriter>
return namebuf;
}
#else
- assert(!exclude_name.empty());
+ ASSERT(!exclude_name.empty());
std::string fname = fmt::format("{}/{}", dir, name);
auto st1 = Stat::lstat(fname);
auto st2 = Stat::stat(fname);