Re: [PATCH v3 1/2] Fix nonnull errors reported by UBSAN with GCC 7.
- From
Junio C Hamano <gitster@pobox.com>
- Date
- Apr 17, 2017, 01:49 UTC
- Message-ID
- <xmqqy3uzkdm4.fsf@gitster.mtv.corp.google.com>
- In-Reply-To
- <96beb4c6-0569-0c12-8151-462c20be6a2a@suse.cz>
Martin Liška <mliska@suse.cz> writes:
Show 7 quoted lines
> From 0bdf4d717d3d368dd9676d15d20f8592c4d22fde Mon Sep 17 00:00:00 2001 > From: marxin <mliska@suse.cz> > Date: Wed, 5 Apr 2017 14:31:32 +0200 > Subject: [PATCH 1/2] Fix nonnull errors reported by UBSAN with GCC 7. > > Replace call to memmove with newly introduced function memmove_or_null > and call to memcpy with COPY_ARRAY macro.
I didn't closely follow the discussion, but with these three lines (which will be the primary thing future readers of this change in "git log -p" output will rely on), it is unclear why this change was made. For that matter, it is not clear what "nonnull errors" are, either.
Show 19 quoted lines
> Signed-off-by: Martin Liska <mliska@suse.cz> > --- > apply.c | 4 +--- > builtin/ls-files.c | 2 +- > git-compat-util.h | 8 ++++++++ > 3 files changed, 10 insertions(+), 4 deletions(-) > > diff --git a/apply.c b/apply.c > index e6dbab26a..121f3f414 100644 > --- a/apply.c > +++ b/apply.c > @@ -2802,9 +2802,7 @@ static void update_image(struct apply_state *state, > img->line + applied_pos + preimage_limit, > (img->nr - (applied_pos + preimage_limit)) * > sizeof(*img->line)); > - memcpy(img->line + applied_pos, > - postimage->line, > - postimage->nr * sizeof(*img->line)); > + COPY_ARRAY(img->line + applied_pos, postimage->line, postimage->nr);
I am suspecting that postimage->nr can be 0 and newer compliers can give warning "hey what's the point of copying 0 bytes?" which can be squelched by moving to COPY_ARRAY()? If that is the case I like the change (but as I said, it is unclear if that is what is going on here).
Show 11 quoted lines
> diff --git a/builtin/ls-files.c b/builtin/ls-files.c > index d449e46db..0a6cc1e8a 100644 > --- a/builtin/ls-files.c > +++ b/builtin/ls-files.c > @@ -391,7 +391,7 @@ static void prune_cache(const char *prefix, size_t prefixlen) > } > last = next; > } > - memmove(active_cache, active_cache + pos, > + memmove_or_null(active_cache, active_cache + pos, > (last - pos) * sizeof(struct cache_entry *));
Does this change come with the same or a similar motivation as the above (i.e. pos could be the same as last)?
"Something or NULL" is a name we use for a function that returns something (under normal circumstances) or returns NULL. This wrapper is not about returning NULL at all, as far as I can see, and is misnamed. If it is about "avoid moving 0 bytes", similar to how COPY_ARRAY() is used in the previous hunk, perhaps MOVE_ARRAY() is a better name?
Thanks.
Show 21 quoted lines
> active_nr = last - pos;
> }
> diff --git a/git-compat-util.h b/git-compat-util.h
> index 8a4a3f85e..81f6e56ac 100644
> --- a/git-compat-util.h
> +++ b/git-compat-util.h
> @@ -1002,6 +1002,14 @@ int git_qsort_s(void *base, size_t nmemb, size_t size,
> die("BUG: qsort_s() failed"); \
> } while (0)
>
> +static inline void *memmove_or_null(void *dest, const void *src, size_t n)
> +{
> + if (n > 0)
> + return memmove(dest, src, n);
> + else
> + return dest;
> +}
> +
> #ifndef REG_STARTEND
> #error "Git requires REG_STARTEND support. Compile with NO_REGEX=NeedsStartEnd"
> #endif