Skip to content

Commit b97b360

Browse files
committed
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
2 parents 9d22ac5 + 5633aa3 commit b97b360

11 files changed

+42
-9
lines changed

Makefile

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2263,6 +2263,10 @@ ifdef WITH_BREAKING_CHANGES
22632263
BASIC_CFLAGS += -DWITH_BREAKING_CHANGES
22642264
endif
22652265

2266+
ifdef CHECK_ASSERTION_SIDE_EFFECTS
2267+
BASIC_CFLAGS += -DCHECK_ASSERTION_SIDE_EFFECTS
2268+
endif
2269+
22662270
ifdef INCLUDE_LIBGIT_RS
22672271
# Enable symbol hiding in contrib/libgit-sys/libgitpub.a without making
22682272
# us rebuild the whole tree every time we run a Rust build.

ci/check-unsafe-assertions.sh

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#!/bin/sh
2+
3+
make CHECK_ASSERTION_SIDE_EFFECTS=1 >compiler_output 2>compiler_error
4+
if test $? != 0
5+
then
6+
echo >&2 "ERROR: The compiler could not verify the following assert()"
7+
echo >&2 " calls are free of side-effects. Please replace with"
8+
echo >&2 " ASSERT() calls."
9+
grep undefined.reference.to..not_supposed_to_survive compiler_error |
10+
sed -e s/:[^:]*$// | sort | uniq | tr ':' ' ' |
11+
while read f l
12+
do
13+
printf "${f}:${l}\n "
14+
awk -v start="$l" 'NR >= start { print; if (/\);/) exit }' $f
15+
done
16+
exit 1
17+
fi
18+
rm compiler_output compiler_error

ci/run-static-analysis.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,6 @@ exit 1
3131

3232
make check-pot
3333

34+
${0%/*}/check-unsafe-assertions.sh
35+
3436
save_good_tree

diffcore-rename.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1406,7 +1406,7 @@ void diffcore_rename_extended(struct diff_options *options,
14061406

14071407
trace2_region_enter("diff", "setup", options->repo);
14081408
info.setup = 0;
1409-
assert(!dir_rename_count || strmap_empty(dir_rename_count));
1409+
ASSERT(!dir_rename_count || strmap_empty(dir_rename_count));
14101410
want_copies = (detect_rename == DIFF_DETECT_COPY);
14111411
if (dirs_removed && (break_idx || want_copies))
14121412
BUG("dirs_removed incompatible with break/copy detection");

git-compat-util.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1460,6 +1460,8 @@ extern int bug_called_must_BUG;
14601460
__attribute__((format (printf, 3, 4))) NORETURN
14611461
void BUG_fl(const char *file, int line, const char *fmt, ...);
14621462
#define BUG(...) BUG_fl(__FILE__, __LINE__, __VA_ARGS__)
1463+
/* ASSERT: like assert(), but won't be compiled out with NDEBUG */
1464+
#define ASSERT(a) if (!(a)) BUG("Assertion `" #a "' failed.")
14631465
__attribute__((format (printf, 3, 4)))
14641466
void bug_fl(const char *file, int line, const char *fmt, ...);
14651467
#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)
15921594
*/
15931595
#define NOT_CONSTANT(expr) ((expr) || false_but_the_compiler_does_not_know_it_)
15941596
extern int false_but_the_compiler_does_not_know_it_;
1597+
1598+
#ifdef CHECK_ASSERTION_SIDE_EFFECTS
1599+
#undef assert
1600+
extern int not_supposed_to_survive;
1601+
#define assert(expr) ((void)(not_supposed_to_survive || (expr)))
1602+
#endif /* CHECK_ASSERTION_SIDE_EFFECTS */
1603+
15951604
#endif

merge-ort.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -791,7 +791,7 @@ static void path_msg(struct merge_options *opt,
791791
struct strbuf tmp = STRBUF_INIT;
792792

793793
/* Sanity checks */
794-
assert(omittable_hint ==
794+
ASSERT(omittable_hint ==
795795
(!starts_with(type_short_descriptions[type], "CONFLICT") &&
796796
!starts_with(type_short_descriptions[type], "ERROR")) ||
797797
type == CONFLICT_DIR_RENAME_SUGGESTED);
@@ -1642,7 +1642,7 @@ static int handle_deferred_entries(struct merge_options *opt,
16421642
ci = strmap_get(&opt->priv->paths, path);
16431643
VERIFY_CI(ci);
16441644

1645-
assert(renames->deferred[side].trivial_merges_okay &&
1645+
ASSERT(renames->deferred[side].trivial_merges_okay &&
16461646
!strset_contains(&renames->deferred[side].target_dirs,
16471647
path));
16481648
resolve_trivial_directory_merge(ci, side);

merge-recursive.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1197,7 +1197,7 @@ static void print_commit(struct repository *repo, struct commit *commit)
11971197
struct pretty_print_context ctx = {0};
11981198
ctx.date_mode.type = DATE_NORMAL;
11991199
/* FIXME: Merge this with output_commit_title() */
1200-
assert(!merge_remote_util(commit));
1200+
ASSERT(!merge_remote_util(commit));
12011201
repo_format_commit_message(repo, commit, " %h: %m %s", &sb, &ctx);
12021202
fprintf(stderr, "%s\n", sb.buf);
12031203
strbuf_release(&sb);

object-file.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2706,7 +2706,7 @@ static int index_stream_convert_blob(struct index_state *istate,
27062706
struct strbuf sbuf = STRBUF_INIT;
27072707

27082708
assert(path);
2709-
assert(would_convert_to_git_filter_fd(istate, path));
2709+
ASSERT(would_convert_to_git_filter_fd(istate, path));
27102710

27112711
convert_to_git_filter_fd(istate, path, fd, &sbuf,
27122712
get_conv_flags(flags));

parallel-checkout.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -277,7 +277,7 @@ static int write_pc_item_to_fd(struct parallel_checkout_item *pc_item, int fd,
277277
ssize_t wrote;
278278

279279
/* Sanity check */
280-
assert(is_eligible_for_parallel_checkout(pc_item->ce, &pc_item->ca));
280+
ASSERT(is_eligible_for_parallel_checkout(pc_item->ce, &pc_item->ca));
281281

282282
filter = get_stream_filter_ca(&pc_item->ca, &pc_item->ce->oid);
283283
if (filter) {

scalar.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,7 +241,7 @@ static int add_or_remove_enlistment(int add)
241241

242242
static int start_fsmonitor_daemon(void)
243243
{
244-
assert(have_fsmonitor_support());
244+
ASSERT(have_fsmonitor_support());
245245

246246
if (fsmonitor_ipc__get_state() != IPC_STATE__LISTENING)
247247
return run_git("fsmonitor--daemon", "start", NULL);
@@ -251,7 +251,7 @@ static int start_fsmonitor_daemon(void)
251251

252252
static int stop_fsmonitor_daemon(void)
253253
{
254-
assert(have_fsmonitor_support());
254+
ASSERT(have_fsmonitor_support());
255255

256256
if (fsmonitor_ipc__get_state() == IPC_STATE__LISTENING)
257257
return run_git("fsmonitor--daemon", "stop", NULL);

0 commit comments

Comments
 (0)