builtins: annotate always-empty prefix parameters

It's usually a bad idea for a builtin's cmd_foo() to ignore the "prefix" argument it gets, as it needs to prepend that string when accessing any paths given by the user. But if a builtin does not ask for the git wrapper to run repository setup (via the RUN_SETUP or RUN_SETUP_GENTLY flags), then we know the prefix will always be NULL (it is adjusting for the chdir() done during repo setup, but there cannot be one if we did not set up the repo). In those cases it's OK to ignore "prefix", but it's worth annotating for a few reasons: 1. It serves as documentation to somebody reading the code about what we expect. 2. If the flags in git.c ever change, the run-time assertion may help detect the problem (though only if the command is run from a subdirectory of the repository). 3. It notes to the compiler that we are OK ignoring "prefix". In particular, this silences -Wunused-parameter. It _could_ also help the compiler generate better code (because it will know the prefix is NULL), but in practice this is quite unlikely to matter. Note that I've only added this annotation to commands which triggered -Wunused-parameter. It would be correct to add it to any builtin which doesn't ask for RUN_SETUP, but most of the rest of them do the sensible thing with "prefix" by passing it to parse_options(). So they're much more likely to just work if they ever switched to RUN_SETUP, and aren't worth annotating. Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Mar 28, 2023 at 16:55 UTC 79156913774ef7c5f72264067e0764a1447a1bb3
7 files changed +22
builtin.h
+10
@@ -107,6 +107,16 @@ void setup_auto_pager(const char *cmd, int def);
107
108 int is_builtin(const char *s);
109
110 +/*
111 + * Builtins which do not use RUN_SETUP should never see
112 + * a prefix that is not empty; use this to protect downstream
113 + * code which is not prepared to call prefix_filename(), etc.
114 + */
115 +#define BUG_ON_NON_EMPTY_PREFIX(prefix) do { \
116 + if ((prefix)) \
117 + BUG("unexpected prefix in builtin: %s", (prefix)); \
118 +} while (0)
119 +
120 int cmd_add(int argc, const char **argv, const char *prefix);
121 int cmd_am(int argc, const char **argv, const char *prefix);
122 int cmd_annotate(int argc, const char **argv, const char *prefix);
builtin/check-ref-format.c
+2
@@ -60,6 +60,8 @@ int cmd_check_ref_format(int argc, const char **argv, const char *prefix)
60 char *to_free = NULL;
61 int ret = 1;
62
63 + BUG_ON_NON_EMPTY_PREFIX(prefix);
64 +
65 if (argc == 2 && !strcmp(argv[1], "-h"))
66 usage(builtin_check_ref_format_usage);
67
builtin/get-tar-commit-id.c
+2
@@ -24,6 +24,8 @@ int cmd_get_tar_commit_id(int argc, const char **argv, const char *prefix)
24 long len;
25 char *end;
26
27 + BUG_ON_NON_EMPTY_PREFIX(prefix);
28 +
29 if (argc != 1)
30 usage(builtin_get_tar_commit_id_usage);
31
builtin/mailsplit.c
+2
@@ -277,6 +277,8 @@ int cmd_mailsplit(int argc, const char **argv, const char *prefix)
277 const char **argp;
278 static const char *stdin_only[] = { "-", NULL };
279
280 + BUG_ON_NON_EMPTY_PREFIX(prefix);
281 +
282 for (argp = argv+1; *argp; argp++) {
283 const char *arg = *argp;
284
builtin/remote-ext.c
+2
@@ -197,6 +197,8 @@ static int command_loop(const char *child)
197
198 int cmd_remote_ext(int argc, const char **argv, const char *prefix)
199 {
200 + BUG_ON_NON_EMPTY_PREFIX(prefix);
201 +
202 if (argc != 3)
203 usage(usage_msg);
204
builtin/remote-fd.c
+2
@@ -59,6 +59,8 @@ int cmd_remote_fd(int argc, const char **argv, const char *prefix)
59 int output_fd = -1;
60 char *end;
61
62 + BUG_ON_NON_EMPTY_PREFIX(prefix);
63 +
64 if (argc != 3)
65 usage(usage_msg);
66
builtin/upload-archive.c
+2
@@ -79,6 +79,8 @@ int cmd_upload_archive(int argc, const char **argv, const char *prefix)
79 {
80 struct child_process writer = CHILD_PROCESS_INIT;
81
82 + BUG_ON_NON_EMPTY_PREFIX(prefix);
83 +
84 if (argc == 2 && !strcmp(argv[1], "-h"))
85 usage(upload_archive_usage);
86