Merge branch 'en/assert-wo-side-effects'
Ensure what we write in assert() does not have side effects, and introduce ASSERT() macro to mark those that cannot be mechanically checked for lack of side effects. * en/assert-wo-side-effects: treewide: replace assert() with ASSERT() in special cases ci: add build checking for side-effects in assert() calls git-compat-util: introduce ASSERT() macro
This commit is contained in:
4
Makefile
4
Makefile
@@ -2263,6 +2263,10 @@ ifdef WITH_BREAKING_CHANGES
|
|||||||
BASIC_CFLAGS += -DWITH_BREAKING_CHANGES
|
BASIC_CFLAGS += -DWITH_BREAKING_CHANGES
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifdef CHECK_ASSERTION_SIDE_EFFECTS
|
||||||
|
BASIC_CFLAGS += -DCHECK_ASSERTION_SIDE_EFFECTS
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef INCLUDE_LIBGIT_RS
|
ifdef INCLUDE_LIBGIT_RS
|
||||||
# Enable symbol hiding in contrib/libgit-sys/libgitpub.a without making
|
# Enable symbol hiding in contrib/libgit-sys/libgitpub.a without making
|
||||||
# us rebuild the whole tree every time we run a Rust build.
|
# us rebuild the whole tree every time we run a Rust build.
|
||||||
|
|||||||
18
ci/check-unsafe-assertions.sh
Executable file
18
ci/check-unsafe-assertions.sh
Executable file
@@ -0,0 +1,18 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
make CHECK_ASSERTION_SIDE_EFFECTS=1 >compiler_output 2>compiler_error
|
||||||
|
if test $? != 0
|
||||||
|
then
|
||||||
|
echo >&2 "ERROR: The compiler could not verify the following assert()"
|
||||||
|
echo >&2 " calls are free of side-effects. Please replace with"
|
||||||
|
echo >&2 " ASSERT() calls."
|
||||||
|
grep undefined.reference.to..not_supposed_to_survive compiler_error |
|
||||||
|
sed -e s/:[^:]*$// | sort | uniq | tr ':' ' ' |
|
||||||
|
while read f l
|
||||||
|
do
|
||||||
|
printf "${f}:${l}\n "
|
||||||
|
awk -v start="$l" 'NR >= start { print; if (/\);/) exit }' $f
|
||||||
|
done
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
rm compiler_output compiler_error
|
||||||
@@ -31,4 +31,6 @@ exit 1
|
|||||||
|
|
||||||
make check-pot
|
make check-pot
|
||||||
|
|
||||||
|
${0%/*}/check-unsafe-assertions.sh
|
||||||
|
|
||||||
save_good_tree
|
save_good_tree
|
||||||
|
|||||||
@@ -1406,7 +1406,7 @@ void diffcore_rename_extended(struct diff_options *options,
|
|||||||
|
|
||||||
trace2_region_enter("diff", "setup", options->repo);
|
trace2_region_enter("diff", "setup", options->repo);
|
||||||
info.setup = 0;
|
info.setup = 0;
|
||||||
assert(!dir_rename_count || strmap_empty(dir_rename_count));
|
ASSERT(!dir_rename_count || strmap_empty(dir_rename_count));
|
||||||
want_copies = (detect_rename == DIFF_DETECT_COPY);
|
want_copies = (detect_rename == DIFF_DETECT_COPY);
|
||||||
if (dirs_removed && (break_idx || want_copies))
|
if (dirs_removed && (break_idx || want_copies))
|
||||||
BUG("dirs_removed incompatible with break/copy detection");
|
BUG("dirs_removed incompatible with break/copy detection");
|
||||||
|
|||||||
@@ -1460,6 +1460,8 @@ extern int bug_called_must_BUG;
|
|||||||
__attribute__((format (printf, 3, 4))) NORETURN
|
__attribute__((format (printf, 3, 4))) NORETURN
|
||||||
void BUG_fl(const char *file, int line, const char *fmt, ...);
|
void BUG_fl(const char *file, int line, const char *fmt, ...);
|
||||||
#define BUG(...) BUG_fl(__FILE__, __LINE__, __VA_ARGS__)
|
#define BUG(...) BUG_fl(__FILE__, __LINE__, __VA_ARGS__)
|
||||||
|
/* ASSERT: like assert(), but won't be compiled out with NDEBUG */
|
||||||
|
#define ASSERT(a) if (!(a)) BUG("Assertion `" #a "' failed.")
|
||||||
__attribute__((format (printf, 3, 4)))
|
__attribute__((format (printf, 3, 4)))
|
||||||
void bug_fl(const char *file, int line, const char *fmt, ...);
|
void bug_fl(const char *file, int line, const char *fmt, ...);
|
||||||
#define bug(...) bug_fl(__FILE__, __LINE__, __VA_ARGS__)
|
#define bug(...) bug_fl(__FILE__, __LINE__, __VA_ARGS__)
|
||||||
@@ -1592,4 +1594,11 @@ static inline void *container_of_or_null_offset(void *ptr, size_t offset)
|
|||||||
*/
|
*/
|
||||||
#define NOT_CONSTANT(expr) ((expr) || false_but_the_compiler_does_not_know_it_)
|
#define NOT_CONSTANT(expr) ((expr) || false_but_the_compiler_does_not_know_it_)
|
||||||
extern int false_but_the_compiler_does_not_know_it_;
|
extern int false_but_the_compiler_does_not_know_it_;
|
||||||
|
|
||||||
|
#ifdef CHECK_ASSERTION_SIDE_EFFECTS
|
||||||
|
#undef assert
|
||||||
|
extern int not_supposed_to_survive;
|
||||||
|
#define assert(expr) ((void)(not_supposed_to_survive || (expr)))
|
||||||
|
#endif /* CHECK_ASSERTION_SIDE_EFFECTS */
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -791,7 +791,7 @@ static void path_msg(struct merge_options *opt,
|
|||||||
struct strbuf tmp = STRBUF_INIT;
|
struct strbuf tmp = STRBUF_INIT;
|
||||||
|
|
||||||
/* Sanity checks */
|
/* Sanity checks */
|
||||||
assert(omittable_hint ==
|
ASSERT(omittable_hint ==
|
||||||
(!starts_with(type_short_descriptions[type], "CONFLICT") &&
|
(!starts_with(type_short_descriptions[type], "CONFLICT") &&
|
||||||
!starts_with(type_short_descriptions[type], "ERROR")) ||
|
!starts_with(type_short_descriptions[type], "ERROR")) ||
|
||||||
type == CONFLICT_DIR_RENAME_SUGGESTED);
|
type == CONFLICT_DIR_RENAME_SUGGESTED);
|
||||||
@@ -1642,7 +1642,7 @@ static int handle_deferred_entries(struct merge_options *opt,
|
|||||||
ci = strmap_get(&opt->priv->paths, path);
|
ci = strmap_get(&opt->priv->paths, path);
|
||||||
VERIFY_CI(ci);
|
VERIFY_CI(ci);
|
||||||
|
|
||||||
assert(renames->deferred[side].trivial_merges_okay &&
|
ASSERT(renames->deferred[side].trivial_merges_okay &&
|
||||||
!strset_contains(&renames->deferred[side].target_dirs,
|
!strset_contains(&renames->deferred[side].target_dirs,
|
||||||
path));
|
path));
|
||||||
resolve_trivial_directory_merge(ci, side);
|
resolve_trivial_directory_merge(ci, side);
|
||||||
|
|||||||
@@ -1197,7 +1197,7 @@ static void print_commit(struct repository *repo, struct commit *commit)
|
|||||||
struct pretty_print_context ctx = {0};
|
struct pretty_print_context ctx = {0};
|
||||||
ctx.date_mode.type = DATE_NORMAL;
|
ctx.date_mode.type = DATE_NORMAL;
|
||||||
/* FIXME: Merge this with output_commit_title() */
|
/* FIXME: Merge this with output_commit_title() */
|
||||||
assert(!merge_remote_util(commit));
|
ASSERT(!merge_remote_util(commit));
|
||||||
repo_format_commit_message(repo, commit, " %h: %m %s", &sb, &ctx);
|
repo_format_commit_message(repo, commit, " %h: %m %s", &sb, &ctx);
|
||||||
fprintf(stderr, "%s\n", sb.buf);
|
fprintf(stderr, "%s\n", sb.buf);
|
||||||
strbuf_release(&sb);
|
strbuf_release(&sb);
|
||||||
|
|||||||
@@ -2706,7 +2706,7 @@ static int index_stream_convert_blob(struct index_state *istate,
|
|||||||
struct strbuf sbuf = STRBUF_INIT;
|
struct strbuf sbuf = STRBUF_INIT;
|
||||||
|
|
||||||
assert(path);
|
assert(path);
|
||||||
assert(would_convert_to_git_filter_fd(istate, path));
|
ASSERT(would_convert_to_git_filter_fd(istate, path));
|
||||||
|
|
||||||
convert_to_git_filter_fd(istate, path, fd, &sbuf,
|
convert_to_git_filter_fd(istate, path, fd, &sbuf,
|
||||||
get_conv_flags(flags));
|
get_conv_flags(flags));
|
||||||
|
|||||||
@@ -277,7 +277,7 @@ static int write_pc_item_to_fd(struct parallel_checkout_item *pc_item, int fd,
|
|||||||
ssize_t wrote;
|
ssize_t wrote;
|
||||||
|
|
||||||
/* Sanity check */
|
/* Sanity check */
|
||||||
assert(is_eligible_for_parallel_checkout(pc_item->ce, &pc_item->ca));
|
ASSERT(is_eligible_for_parallel_checkout(pc_item->ce, &pc_item->ca));
|
||||||
|
|
||||||
filter = get_stream_filter_ca(&pc_item->ca, &pc_item->ce->oid);
|
filter = get_stream_filter_ca(&pc_item->ca, &pc_item->ce->oid);
|
||||||
if (filter) {
|
if (filter) {
|
||||||
|
|||||||
4
scalar.c
4
scalar.c
@@ -241,7 +241,7 @@ static int add_or_remove_enlistment(int add)
|
|||||||
|
|
||||||
static int start_fsmonitor_daemon(void)
|
static int start_fsmonitor_daemon(void)
|
||||||
{
|
{
|
||||||
assert(have_fsmonitor_support());
|
ASSERT(have_fsmonitor_support());
|
||||||
|
|
||||||
if (fsmonitor_ipc__get_state() != IPC_STATE__LISTENING)
|
if (fsmonitor_ipc__get_state() != IPC_STATE__LISTENING)
|
||||||
return run_git("fsmonitor--daemon", "start", NULL);
|
return run_git("fsmonitor--daemon", "start", NULL);
|
||||||
@@ -251,7 +251,7 @@ static int start_fsmonitor_daemon(void)
|
|||||||
|
|
||||||
static int stop_fsmonitor_daemon(void)
|
static int stop_fsmonitor_daemon(void)
|
||||||
{
|
{
|
||||||
assert(have_fsmonitor_support());
|
ASSERT(have_fsmonitor_support());
|
||||||
|
|
||||||
if (fsmonitor_ipc__get_state() == IPC_STATE__LISTENING)
|
if (fsmonitor_ipc__get_state() == IPC_STATE__LISTENING)
|
||||||
return run_git("fsmonitor--daemon", "stop", NULL);
|
return run_git("fsmonitor--daemon", "stop", NULL);
|
||||||
|
|||||||
@@ -4965,7 +4965,7 @@ static int pick_commits(struct repository *r,
|
|||||||
|
|
||||||
ctx->reflog_message = sequencer_reflog_action(opts);
|
ctx->reflog_message = sequencer_reflog_action(opts);
|
||||||
if (opts->allow_ff)
|
if (opts->allow_ff)
|
||||||
assert(!(opts->signoff || opts->no_commit ||
|
ASSERT(!(opts->signoff || opts->no_commit ||
|
||||||
opts->record_origin || should_edit(opts) ||
|
opts->record_origin || should_edit(opts) ||
|
||||||
opts->committer_date_is_author_date ||
|
opts->committer_date_is_author_date ||
|
||||||
opts->ignore_date));
|
opts->ignore_date));
|
||||||
|
|||||||
Reference in New Issue
Block a user