summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoel Rosdahl <joel@rosdahl.net>2018-08-08 14:50:44 +0200
committerJoel Rosdahl <joel@rosdahl.net>2018-08-08 14:50:44 +0200
commit2d57113eaa407bb92de51a3eb41cdd8cca820e3a (patch)
tree098c6fc5a8a566eea5b0437e3e25154f7700efd8
parent43dbeffef5bb55c58ebfbb217f17efd63025670e (diff)
parenta5840dad77f7e468a1f28f2a69a82fa9de7f10d0 (diff)
downloadccache-2d57113eaa407bb92de51a3eb41cdd8cca820e3a.tar.gz
Merge branch 'master' into dev/memcached
* master: (27 commits) Add configure option to disable man pages Remove debug log Improve logging related to hashing of the CWD Improve installation instructions Update NEWS Avoid TOCTOU issue when deciding if config is valid Fix code style hashutil: fix memory-leak/double free Fix some casting warnings Update NEWS Add the sanitize blacklist contents to the hash Update NEWS Simplify logic Print the time when stats last updated Use double when calculating cache thresholds Add a 32-bit build target, using multilib (-m32) Convert float config to double, add rounding Upgrade clang to 5.0, for the Travis docker Make sure to export ASAN_OPTIONS properly Add small helper to run all Travis tests ...
-rwxr-xr-x.travis.sh9
-rw-r--r--.travis.yml33
-rw-r--r--.travis/Dockerfile37
-rw-r--r--Makefile.in6
-rw-r--r--configure.ac8
-rw-r--r--dev.mk.in9
-rw-r--r--doc/INSTALL-from-release-archive.md7
-rw-r--r--doc/INSTALL.md6
-rw-r--r--doc/NEWS.adoc17
-rw-r--r--src/ccache.c30
-rw-r--r--src/ccache.h2
-rw-r--r--src/cleanup.c26
-rw-r--r--src/conf.c6
-rw-r--r--src/execute.c3
-rw-r--r--src/hashtable.c2
-rw-r--r--src/hashutil.c2
-rw-r--r--src/snprintf.c4
-rw-r--r--src/stats.c11
-rw-r--r--src/util.c2
-rwxr-xr-xtest/run1
-rw-r--r--test/suites/cleanup.bash6
-rw-r--r--test/suites/debug_prefix_map.bash3
-rw-r--r--test/suites/sanitize_blacklist.bash58
-rw-r--r--unittest/test_conf.c16
24 files changed, 253 insertions, 51 deletions
diff --git a/.travis.sh b/.travis.sh
new file mode 100755
index 00000000..ad646783
--- /dev/null
+++ b/.travis.sh
@@ -0,0 +1,9 @@
+#!/bin/sh -ex
+make clean
+make travis CC=gcc
+make travis CC=clang
+make travis CC=gcc CFLAGS="-m32 -g -O2" HOST="--host=i386-linux-gnu"
+make travis CC=i686-w64-mingw32-gcc HOST="--host=i686-w64-mingw32" TEST="unittest/run.exe"
+make travis CC=clang CFLAGS="-fsanitize=undefined" ASAN_OPTIONS="detect_leaks=0"
+make travis CC=clang CFLAGS="-fsanitize=address -g" ASAN_OPTIONS="detect_leaks=0"
+make travis CC=/usr/bin/clang TEST=analyze
diff --git a/.travis.yml b/.travis.yml
index c1bf724c..90084093 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,27 +1,23 @@
language: c
-sudo: required
-
addons:
apt:
packages:
- gperf
- elfutils
- zlib1g-dev
+ - lib32z1-dev
- libmemcached-dev
- libmemcached-tools
- memcached
- - mingw32
- - mingw32-binutils
- - clang # scan-build
os:
- linux
- osx
compiler:
- - clang
- gcc
+ - clang
matrix:
include:
@@ -30,9 +26,18 @@ matrix:
sudo: required
dist: trusty
env: FEATURES="--enable-memcached"
-# - os: linux
-# compiler: i586-mingw32msvc-gcc
-# env: HOST="--host=i586-mingw32msvc" TEST="test/main.exe"
+ env: CFLAGS="-m32 -g -O2" HOST="--host=i386-linux-gnu"
+ addons:
+ apt:
+ packages:
+ - gcc-multilib
+ - os: linux
+ compiler: i686-w64-mingw32-gcc
+ env: HOST="--host=i686-w64-mingw32" TEST="unittest/run.exe"
+ addons:
+ apt:
+ packages:
+ - gcc-mingw-w64-i686
- os: linux
compiler: clang
env: CFLAGS="-fsanitize=undefined" ASAN_OPTIONS="detect_leaks=0"
@@ -42,17 +47,21 @@ matrix:
- os: linux
compiler: clang
env: PATH="/usr/bin:$PATH" TEST=analyze
+ addons:
+ apt:
+ packages:
+ - clang # scan-build
- os: linux
compiler: gcc
env: CUDA=8.0.61-1
+ sudo: required
+ before_install:
+ - source ./.travis/install_cuda.sh
exclude:
- os: osx
compiler: gcc
-before_install:
- - source ./.travis/install_cuda.sh
-
script:
- ./autogen.sh
- ./configure $HOST $FEATURES
diff --git a/.travis/Dockerfile b/.travis/Dockerfile
new file mode 100644
index 00000000..5f837b0e
--- /dev/null
+++ b/.travis/Dockerfile
@@ -0,0 +1,37 @@
+# NOTE: This is not the real Docker image used for the Travis builds.
+# See: https://docs.travis-ci.com/user/common-build-problems/
+
+FROM ubuntu:trusty
+
+# https://github.com/Yelp/dumb-init
+ADD https://github.com/Yelp/dumb-init/releases/download/v1.2.1/dumb-init_1.2.1_amd64.deb .
+RUN dpkg -i dumb-init_*.deb
+ENTRYPOINT ["/usr/bin/dumb-init", "--"]
+
+# generic tools
+RUN apt-get -qq update && apt-get install -y --no-install-recommends \
+ libc6-dev \
+ gcc \
+ clang \
+ libc6-dev-i386 \
+ gcc-multilib \
+ gcc-mingw-w64 \
+ make \
+ autoconf \
+ && rm -rf /var/lib/apt/lists/*
+
+# Travis has upgraded clang, from clang-3.4 to clang-5.0
+# https://github.com/travis-ci/travis-cookbooks/pull/890
+RUN printf "deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main\ndeb-src http://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main\n# Also add the following for the appropriate libstdc++\ndeb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu trusty main\n" > /etc/apt/sources.list.d/llvm-toolchain.list && apt-key adv --fetch-keys http://apt.llvm.org/llvm-snapshot.gpg.key && apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 1E9377A2BA9EF27F
+RUN apt-get -qq update && apt-get install -y --no-install-recommends \
+ clang-5.0 \
+ && rm -rf /var/lib/apt/lists/* \
+ && ln -s /usr/bin/clang-5.0 /usr/local/bin/clang
+
+# ccache specific
+RUN apt-get -qq update && apt-get install -y --no-install-recommends \
+ gperf \
+ elfutils \
+ zlib1g-dev \
+ lib32z1-dev \
+ && rm -rf /var/lib/apt/lists/*
diff --git a/Makefile.in b/Makefile.in
index dad4343e..705dfc1a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -102,11 +102,11 @@ ccache.1: doc/ccache.1
cp $< $@
.PHONY: install
-install: ccache$(EXEEXT) ccache.1
+install: ccache$(EXEEXT) @disable_man@ccache.1
$(installcmd) -d $(DESTDIR)$(bindir)
$(installcmd) -m 755 ccache$(EXEEXT) $(DESTDIR)$(bindir)
- $(installcmd) -d $(DESTDIR)$(mandir)/man1
- -$(installcmd) -m 644 ccache.1 $(DESTDIR)$(mandir)/man1/
+@disable_man@ $(installcmd) -d $(DESTDIR)$(mandir)/man1
+@disable_man@ -$(installcmd) -m 644 ccache.1 $(DESTDIR)$(mandir)/man1/
.PHONY: clean
clean:
diff --git a/configure.ac b/configure.ac
index 43803c10..85acb3d3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,6 +20,7 @@ AC_SUBST(ccache_memcached)
AC_SUBST(extra_libs)
AC_SUBST(include_dev_mk)
AC_SUBST(test_suites)
+AC_SUBST(disable_man)
m4_include(m4/feature_macros.m4)
@@ -152,6 +153,13 @@ else
LIBS="$LIBS -lz"
fi
+AC_ARG_ENABLE(man,
+ [AS_HELP_STRING([--disable-man],
+ [disable installing man pages])])
+if test x${enable_man} = xno; then
+ disable_man='#'
+fi
+
dnl Linking on Windows needs ws2_32
if test x${windows_os} = xyes; then
LIBS="$LIBS -lws2_32"
diff --git a/dev.mk.in b/dev.mk.in
index 91b0a578..fd599b82 100644
--- a/dev.mk.in
+++ b/dev.mk.in
@@ -10,6 +10,7 @@ CPPCHECK_SUPPRESSIONS = misc/cppcheck-suppressions.txt
SCAN_BUILD = scan-build
DOCKER = docker
GPERF = gperf
+TEST = test
version := \
$(shell (git --git-dir=$(srcdir)/.git describe --dirty || git --git-dir=$(srcdir)/.git describe || echo vunknown) \
@@ -196,11 +197,17 @@ uncrustify:
.PHONY: analyze
analyze:
- $(SCAN_BUILD) --use-cc=$(CC) ./configure
+ $(SCAN_BUILD) --use-cc=$(CC) $(srcdir)/configure
$(SCAN_BUILD) --use-cc=$(CC) --status-bugs $(MAKE) -B
.PHONY: docker
docker: misc/Dockerfile
$(DOCKER) build -f $< $(srcdir)
+.PHONY: travis
+travis: .travis/Dockerfile
+ $(DOCKER) inspect travis-build >/dev/null || $(DOCKER) build -t travis-build .travis
+ $(DOCKER) run --rm --volume $(PWD):/src --tmpfs /dst:rw,exec --env ASAN_OPTIONS='$(ASAN_OPTIONS)' travis-build \
+ sh -c "cd /src && ./autogen.sh && cd /dst && CC=$(CC) CFLAGS='$(CFLAGS)' /src/configure $(HOST) && make && make $(TEST)"
+
-include .deps/*.d
diff --git a/doc/INSTALL-from-release-archive.md b/doc/INSTALL-from-release-archive.md
index be25d028..e5e335d4 100644
--- a/doc/INSTALL-from-release-archive.md
+++ b/doc/INSTALL-from-release-archive.md
@@ -1,10 +1,11 @@
-ccache installation
-===================
+ccache installation from release archive
+========================================
Prerequisites
-------------
-To build ccache, you need:
+To build ccache from a
+[release archive](https://ccache.samba.org/download.html), you need:
- A C compiler (for instance GCC)
diff --git a/doc/INSTALL.md b/doc/INSTALL.md
index d0531943..4d2a55ca 100644
--- a/doc/INSTALL.md
+++ b/doc/INSTALL.md
@@ -1,10 +1,10 @@
-ccache installation
-===================
+ccache installation from source repository
+==========================================
Prerequisites
-------------
-To build ccache from the source repository, you need:
+To build ccache from a source repository, you need:
- A C compiler (for instance GCC)
- GNU Bourne Again SHell (bash) for tests.
diff --git a/doc/NEWS.adoc b/doc/NEWS.adoc
index a504d27a..1abc33c9 100644
--- a/doc/NEWS.adoc
+++ b/doc/NEWS.adoc
@@ -16,6 +16,23 @@ New features and enhancements
precompiled headers. Note that the build system needs to keep the checksum
file in sync with the precompiled header for this to work.
+- Added ``stats updated'' timestamp in `ccache -s` output. This can be useful
+ if you wonder whether ccache actually was used for your last build.
+
+- The content of the `-fsanitize-blacklist` file is now included in the hash,
+ so updates to the file will now correctly result in separate cache entries.
+
+
+ccache 3.4.3
+-----------
+Release date: unknown
+
+Bug fixes
+~~~~~~~~~
+
+- Fixed a race condition when creating the initial config file in the cache
+ directory.
+
ccache 3.4.2
------------
diff --git a/src/ccache.c b/src/ccache.c
index ded6af6a..0a8ae9e8 100644
--- a/src/ccache.c
+++ b/src/ccache.c
@@ -239,6 +239,9 @@ static char *profile_dir = NULL;
static bool profile_use = false;
static bool profile_generate = false;
+// Sanitize blacklist
+static char *sanitize_blacklist = NULL;
+
// Whether we are using a precompiled header (either via -include, #include or
// clang's -include-pch or -include-pth).
static bool using_precompiled_header = false;
@@ -1944,7 +1947,7 @@ calculate_common_hash(struct args *args, struct mdfour *hash)
if (sep) {
char *old = x_strndup(map, sep - map);
char *new = x_strdup(sep + 1);
- cc_log("Relocating debuginfo cwd %s, from %s to %s", cwd, old, new);
+ cc_log("Relocating debuginfo CWD %s from %s to %s", cwd, old, new);
if (str_startswith(cwd, old)) {
char *dir = format("%s%s", new, cwd + strlen(old));
free(cwd);
@@ -1955,6 +1958,7 @@ calculate_common_hash(struct args *args, struct mdfour *hash)
}
}
if (cwd) {
+ cc_log("Hashing CWD %s", cwd);
hash_delimiter(hash, "cwd");
hash_string(hash, cwd);
free(cwd);
@@ -1984,6 +1988,16 @@ calculate_common_hash(struct args *args, struct mdfour *hash)
}
}
+ // Possibly hash the sanitize blacklist file path.
+ if (sanitize_blacklist) {
+ cc_log("Hashing sanitize blacklist %s", sanitize_blacklist);
+ hash_delimiter(hash, "sanitizeblacklist");
+ if (!hash_file(hash, sanitize_blacklist)) {
+ stats_update(STATS_BADEXTRAFILE);
+ failed();
+ }
+ }
+
if (!str_eq(conf->extra_files_to_hash, "")) {
char *p = x_strdup(conf->extra_files_to_hash);
char *q = p;
@@ -2130,8 +2144,8 @@ calculate_object_hash(struct args *args, struct mdfour *hash, int direct_mode)
if ((str_eq(args->argv[i], "-ccbin")
|| str_eq(args->argv[i], "--compiler-bindir"))
- && i + 1 < args->argc
- && x_stat(args->argv[i+1], &st) == 0) {
+ && i + 1 < args->argc
+ && x_stat(args->argv[i+1], &st) == 0) {
found_ccbin = true;
hash_delimiter(hash, "ccbin");
hash_nvcc_host_compiler(hash, &st, args->argv[i+1]);
@@ -2987,6 +3001,11 @@ cc_process_args(struct args *args, struct args **preprocessor_args,
args_add(stripped_args, argv[i]);
continue;
}
+ if (str_startswith(argv[i], "-fsanitize-blacklist=")) {
+ sanitize_blacklist = x_strdup(argv[i] + 21);
+ args_add(stripped_args, argv[i]);
+ continue;
+ }
if (str_startswith(argv[i], "--sysroot=")) {
char *relpath = make_relative_path(x_strdup(argv[i] + 10));
char *option = format("--sysroot=%s", relpath);
@@ -3624,7 +3643,7 @@ initialize(void)
} else {
secondary_config_path = format("%s/ccache.conf", TO_STRING(SYSCONFDIR));
if (!conf_read(conf, secondary_config_path, &errmsg)) {
- if (access(secondary_config_path, R_OK) == 0) {
+ if (errno == 0) {
// We could read the file but it contained errors.
fatal("%s", errmsg);
}
@@ -3648,7 +3667,7 @@ initialize(void)
bool should_create_initial_config = false;
if (!conf_read(conf, primary_config_path, &errmsg)) {
- if (access(primary_config_path, R_OK) == 0) {
+ if (errno == 0) {
// We could read the file but it contained errors.
fatal("%s", errmsg);
}
@@ -3706,6 +3725,7 @@ cc_reset(void)
free(debug_prefix_maps); debug_prefix_maps = NULL;
debug_prefix_maps_len = 0;
free(profile_dir); profile_dir = NULL;
+ free(sanitize_blacklist); sanitize_blacklist = NULL;
free(included_pch_file); included_pch_file = NULL;
args_free(orig_args); orig_args = NULL;
free(input_file); input_file = NULL;
diff --git a/src/ccache.h b/src/ccache.h
index c0212539..ae0b0afc 100644
--- a/src/ccache.h
+++ b/src/ccache.h
@@ -251,7 +251,7 @@ void exitfn_call(void);
// ----------------------------------------------------------------------------
// cleanup.c
-void clean_up_dir(struct conf *conf, const char *dir, float limit_multiple);
+void clean_up_dir(struct conf *conf, const char *dir, double limit_multiple);
void clean_up_all(struct conf *conf);
void wipe_all(struct conf *conf);
diff --git a/src/cleanup.c b/src/cleanup.c
index 8c46eac5..607e5dbb 100644
--- a/src/cleanup.c
+++ b/src/cleanup.c
@@ -17,6 +17,8 @@
#include "ccache.h"
+#include <math.h>
+
static struct files {
char *fname;
time_t mtime;
@@ -155,15 +157,16 @@ sort_and_clean(void)
// Clean up one cache subdirectory.
void
-clean_up_dir(struct conf *conf, const char *dir, float limit_multiple)
+clean_up_dir(struct conf *conf, const char *dir, double limit_multiple)
{
cc_log("Cleaning up cache directory %s", dir);
// When "max files" or "max cache size" is reached, one of the 16 cache
// subdirectories is cleaned up. When doing so, files are deleted (in LRU
// order) until the levels are below limit_multiple.
- cache_size_threshold = conf->max_size * limit_multiple / 16;
- files_in_cache_threshold = conf->max_files * limit_multiple / 16;
+ cache_size_threshold = (uint64_t)round(conf->max_size * limit_multiple / 16);
+ files_in_cache_threshold =
+ (size_t)round(conf->max_files * limit_multiple / 16);
num_files = 0;
cache_size = 0;
@@ -173,13 +176,13 @@ clean_up_dir(struct conf *conf, const char *dir, float limit_multiple)
traverse(dir, traverse_fn);
// Clean the cache.
- cc_log("Before cleanup: %lu KiB, %zu files",
- (unsigned long)cache_size / 1024,
- files_in_cache);
+ cc_log("Before cleanup: %.0f KiB, %.0f files",
+ (double)cache_size / 1024,
+ (double)files_in_cache);
bool cleaned = sort_and_clean();
- cc_log("After cleanup: %lu KiB, %zu files",
- (unsigned long)cache_size / 1024,
- files_in_cache);
+ cc_log("After cleanup: %.0f KiB, %.0f files",
+ (double)cache_size / 1024,
+ (double)files_in_cache);
if (cleaned) {
cc_log("Cleaned up cache directory %s", dir);
@@ -236,11 +239,10 @@ static void wipe_fn(const char *fname, struct stat *st)
// Wipe one cache subdirectory.
void
-wipe_dir(struct conf *conf, const char *dir)
+wipe_dir(const char *dir)
{
cc_log("Clearing out cache directory %s", dir);
- files_in_cache_threshold = conf->max_files * conf->limit_multiple / 16;
files_in_cache = 0;
traverse(dir, wipe_fn);
@@ -258,7 +260,7 @@ void wipe_all(struct conf *conf)
{
for (int i = 0; i <= 0xF; i++) {
char *dname = format("%s/%1x", conf->cache_dir, i);
- wipe_dir(conf, dname);
+ wipe_dir(dname);
free(dname);
}
diff --git a/src/conf.c b/src/conf.c
index ca310d17..2e48a4b0 100644
--- a/src/conf.c
+++ b/src/conf.c
@@ -381,11 +381,14 @@ conf_free(struct conf *conf)
free(conf->prefix_command);
free(conf->prefix_command_cpp);
free(conf->temporary_dir);
- free(conf->item_origins);
+ free((void *)conf->item_origins); // Workaround for MSVC warning
free(conf);
}
// Note: The path pointer is stored in conf, so path must outlive conf.
+//
+// On failure, if an I/O error occured errno is set approriately, otherwise
+// errno is set to zero indicating that config itself was invalid.
bool
conf_read(struct conf *conf, const char *path, char **errmsg)
{
@@ -416,6 +419,7 @@ conf_read(struct conf *conf, const char *path, char **errmsg)
if (!ok) {
*errmsg = format("%s:%u: %s", path, line_number, errmsg2);
free(errmsg2);
+ errno = 0;
result = false;
goto out;
}
diff --git a/src/execute.c b/src/execute.c
index df8fe5b6..8c4849a9 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -40,7 +40,7 @@ win32argvtos(char *prefix, char **argv)
break;
case '"':
bs = (bs << 1) + 1;
- // Fallthrough.
+ // Fallthrough.
default:
k += bs + 1;
bs = 0;
@@ -115,6 +115,7 @@ win32getshell(char *path)
void add_exe_ext_if_no_to_fullpath(char *full_path_win_ext, size_t max_size,
const char *ext, const char *path) {
if (!ext || (!str_eq(".exe", ext)
+ && !str_eq(".sh", ext)
&& !str_eq(".bat", ext)
&& !str_eq(".EXE", ext)
&& !str_eq(".BAT", ext))) {
diff --git a/src/hashtable.c b/src/hashtable.c
index 02ab4542..29cf78ab 100644
--- a/src/hashtable.c
+++ b/src/hashtable.c
@@ -51,7 +51,7 @@ static const unsigned int primes[] = {
805306457, 1610612741
};
const unsigned int prime_table_length = sizeof(primes)/sizeof(primes[0]);
-const float max_load_factor = 0.65;
+const float max_load_factor = 0.65f;
/*****************************************************************************/
struct hashtable *
diff --git a/src/hashutil.c b/src/hashutil.c
index ddbd0daa..0086bf7f 100644
--- a/src/hashutil.c
+++ b/src/hashutil.c
@@ -220,7 +220,7 @@ hash_command_output(struct mdfour *hash, const char *command,
CloseHandle(pipe_out[1]);
args_free(args);
free(win32args);
- if (cmd) {
+ if (!cmd) {
free((char *)command); // Original argument was replaced above.
}
if (ret == 0) {
diff --git a/src/snprintf.c b/src/snprintf.c
index b935ee93..bc72a5f3 100644
--- a/src/snprintf.c
+++ b/src/snprintf.c
@@ -1202,7 +1202,7 @@ again:
* Factor of ten with the number of digits needed for the fractional
* part. For example, if the precision is 3, the mask will be 1000.
*/
- mask = mypow10(precision);
+ mask = (UINTMAX_T)mypow10(precision);
/*
* We "cheat" by converting the fractional part to integer by
* multiplying by a factor of ten.
@@ -1454,7 +1454,7 @@ cast(LDOUBLE value)
if (value >= UINTMAX_MAX)
return UINTMAX_MAX;
- result = value;
+ result = (UINTMAX_T)value;
/*
* At least on NetBSD/sparc64 3.0.2 and 4.99.30, casting long double to
* an integer type converts e.g. 1.9 to 2 instead of 1 (which violates
diff --git a/src/stats.c b/src/stats.c
index 5ac56fdc..deca55ff 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -445,6 +445,8 @@ stats_summary(struct conf *conf)
{
struct counters *counters = counters_init(STATS_END);
time_t oldest = 0;
+ time_t updated = 0;
+ struct stat st;
assert(conf);
@@ -464,6 +466,9 @@ stats_summary(struct conf *conf)
if (current != 0 && (oldest == 0 || current < oldest)) {
oldest = current;
}
+ if (stat(fname, &st) == 0 && st.st_mtime > updated) {
+ updated = st.st_mtime;
+ }
free(fname);
}
@@ -478,6 +483,12 @@ stats_summary(struct conf *conf)
strftime(timestamp, sizeof(timestamp), "%c", tm);
printf("stats zero time %s\n", timestamp);
}
+ if (updated) {
+ struct tm *tm = localtime(&updated);
+ char timestamp[100];
+ strftime(timestamp, sizeof(timestamp), "%c", tm);
+ printf("stats updated %s\n", timestamp);
+ }
// ...and display them.
for (int i = 0; stats_info[i].message; i++) {
diff --git a/src/util.c b/src/util.c
index 31773bca..859889ec 100644
--- a/src/util.c
+++ b/src/util.c
@@ -1053,7 +1053,7 @@ parse_size_with_suffix(const char *str, uint64_t *size)
// Default suffix: G.
x *= 1000 * 1000 * 1000;
}
- *size = x;
+ *size = (uint64_t)x;
return true;
}
diff --git a/test/run b/test/run
index d3453b0d..8a44e4f8 100755
--- a/test/run
+++ b/test/run
@@ -410,6 +410,7 @@ nocpp2
cpp1
multi_arch
serialize_diagnostics
+sanitize_blacklist
debug_prefix_map
masquerading
hardlink
diff --git a/test/suites/cleanup.bash b/test/suites/cleanup.bash
index 8eaac4f6..f36dc75c 100644
--- a/test/suites/cleanup.bash
+++ b/test/suites/cleanup.bash
@@ -87,7 +87,7 @@ SUITE_cleanup() {
prepare_cleanup_test_dir $CCACHE_DIR/a
$CCACHE -F 0 -M 256K >/dev/null
- CCACHE_LOGFILE=/tmp/foo $CCACHE -c >/dev/null
+ $CCACHE -c >/dev/null
expect_file_count 3 '*.o' $CCACHE_DIR
expect_file_count 4 '*.d' $CCACHE_DIR
expect_file_count 4 '*.stderr' $CCACHE_DIR
@@ -152,7 +152,7 @@ SUITE_cleanup() {
TEST ".o file is removed before .stderr"
prepare_cleanup_test_dir $CCACHE_DIR/a
- $CCACHE -F 474 -M 0 >/dev/null
+ $CCACHE -F 464 -M 0 >/dev/null
backdate 0 $CCACHE_DIR/a/result9-4017.stderr
$CCACHE -c >/dev/null
expect_file_missing $CCACHE_DIR/a/result9-4017.stderr
@@ -167,7 +167,7 @@ SUITE_cleanup() {
TEST ".stderr file is not removed before .o"
prepare_cleanup_test_dir $CCACHE_DIR/a
- $CCACHE -F 474 -M 0 >/dev/null
+ $CCACHE -F 464 -M 0 >/dev/null
backdate 0 $CCACHE_DIR/a/result9-4017.o
$CCACHE -c >/dev/null
expect_file_exists $CCACHE_DIR/a/result9-4017.stderr
diff --git a/test/suites/debug_prefix_map.bash b/test/suites/debug_prefix_map.bash
index 256d4cbc..25cc36ff 100644
--- a/test/suites/debug_prefix_map.bash
+++ b/test/suites/debug_prefix_map.bash
@@ -1,5 +1,6 @@
SUITE_debug_prefix_map_PROBE() {
- if $COMPILER_USES_MINGW; then
+ touch test.c
+ if ! $REAL_COMPILER -c -fdebug-prefix-map=old=new test.c 2>/dev/null; then
echo "-fdebug-prefix-map not supported by compiler"
fi
}
diff --git a/test/suites/sanitize_blacklist.bash b/test/suites/sanitize_blacklist.bash
new file mode 100644
index 00000000..a2411e9b
--- /dev/null
+++ b/test/suites/sanitize_blacklist.bash
@@ -0,0 +1,58 @@
+SUITE_sanitize_blacklist_PROBE() {
+ touch test.c blacklist.txt
+ if ! $REAL_COMPILER -c -fsanitize-blacklist=blacklist.txt \
+ test.c 2>/dev/null; then
+ echo "-fsanitize-blacklist not supported by compiler"
+ fi
+}
+
+SUITE_sanitize_blacklist_SETUP() {
+ generate_code 1 test1.c
+ echo "fun:foo" >blacklist.txt
+
+ unset CCACHE_NODIRECT
+}
+
+SUITE_sanitize_blacklist() {
+ # -------------------------------------------------------------------------
+ TEST "Compile OK"
+
+ $REAL_COMPILER -c -fsanitize-blacklist=blacklist.txt test1.c
+
+ $CCACHE_COMPILE -c -fsanitize-blacklist=blacklist.txt test1.c
+ expect_stat 'cache hit (direct)' 0
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' 2
+
+ $CCACHE_COMPILE -c -fsanitize-blacklist=blacklist.txt test1.c
+ expect_stat 'cache hit (direct)' 1
+ expect_stat 'cache miss' 1
+ expect_stat 'files in cache' 2
+
+ echo "fun:bar" >blacklist.txt
+
+ $CCACHE_COMPILE -c -fsanitize-blacklist=blacklist.txt test1.c
+ expect_stat 'cache hit (direct)' 1
+ expect_stat 'cache miss' 2
+ expect_stat 'files in cache' 4
+
+ $CCACHE_COMPILE -c -fsanitize-blacklist=blacklist.txt test1.c
+ expect_stat 'cache hit (direct)' 2
+ expect_stat 'cache miss' 2
+ expect_stat 'files in cache' 4
+
+ # -------------------------------------------------------------------------
+ TEST "Compile failed"
+
+ if $REAL_COMPILER -c -fsanitize-blacklist=nosuchfile.txt test1.c 2>expected.stderr; then
+ test_failed "Expected an error compiling test1.c"
+ fi
+
+ rm blacklist.txt
+
+ if $CCACHE_COMPILE -c -fsanitize-blacklist=blacklist.txt test1.c 2>expected.stderr; then
+ test_failed "Expected an error compiling test1.c"
+ fi
+
+ expect_stat 'error hashing extra file' 1
+}
diff --git a/unittest/test_conf.c b/unittest/test_conf.c
index 4773f8b1..889a13e2 100644
--- a/unittest/test_conf.c
+++ b/unittest/test_conf.c
@@ -195,6 +195,7 @@ TEST(conf_read_with_missing_equal_sign)
char *errmsg;
create_file("ccache.conf", "no equal sign");
CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+ CHECK_INT_EQ(errno, 0);
CHECK_STR_EQ_FREE2("ccache.conf:1: missing equal sign",
errmsg);
conf_free(conf);
@@ -206,6 +207,7 @@ TEST(conf_read_with_bad_config_key)
char *errmsg;
create_file("ccache.conf", "# Comment\nfoo = bar");
CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+ CHECK_INT_EQ(errno, 0);
CHECK_STR_EQ_FREE2("ccache.conf:2: unknown configuration option \"foo\"",
errmsg);
conf_free(conf);
@@ -218,11 +220,13 @@ TEST(conf_read_invalid_bool)
create_file("ccache.conf", "disable=");
CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+ CHECK_INT_EQ(errno, 0);
CHECK_STR_EQ_FREE2("ccache.conf:1: not a boolean value: \"\"",
errmsg);
create_file("ccache.conf", "disable=foo");
CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+ CHECK_INT_EQ(errno, 0);
CHECK_STR_EQ_FREE2("ccache.conf:1: not a boolean value: \"foo\"",
errmsg);
conf_free(conf);
@@ -234,6 +238,7 @@ TEST(conf_read_invalid_env_string)
char *errmsg;
create_file("ccache.conf", "base_dir = ${foo");
CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+ CHECK_INT_EQ(errno, 0);
CHECK_STR_EQ_FREE2("ccache.conf:1: syntax error: missing '}' after \"foo\"",
errmsg);
// Other cases tested in test_util.c.
@@ -256,6 +261,7 @@ TEST(conf_read_invalid_size)
char *errmsg;
create_file("ccache.conf", "max_size = foo");
CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+ CHECK_INT_EQ(errno, 0);
CHECK_STR_EQ_FREE2("ccache.conf:1: invalid size: \"foo\"",
errmsg);
// Other cases tested in test_util.c.
@@ -268,6 +274,7 @@ TEST(conf_read_invalid_sloppiness)
char *errmsg;
create_file("ccache.conf", "sloppiness = file_macro, foo");
CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+ CHECK_INT_EQ(errno, 0);
CHECK_STR_EQ_FREE2("ccache.conf:1: unknown sloppiness: \"foo\"",
errmsg);
conf_free(conf);
@@ -280,6 +287,7 @@ TEST(conf_read_invalid_unsigned)
create_file("ccache.conf", "max_files =");
CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+ CHECK_INT_EQ(errno, 0);
CHECK_STR_EQ_FREE2("ccache.conf:1: invalid unsigned integer: \"\"",
errmsg);
@@ -296,6 +304,14 @@ TEST(conf_read_invalid_unsigned)
conf_free(conf);
}
+TEST(conf_read_missing_config_file)
+{
+ struct conf *conf = conf_create();
+ char *errmsg;
+ CHECK(!conf_read(conf, "ccache.conf", &errmsg));
+ CHECK_INT_EQ(errno, ENOENT);
+}
+
TEST(verify_absolute_base_dir)
{
struct conf *conf = conf_create();