* -Wunterminated-string-initialization warning with GCC 15 in object-file.c
@ 2024-11-17 2:50 Sam James
2024-11-17 9:03 ` Jeff King
0 siblings, 1 reply; 25+ messages in thread
From: Sam James @ 2024-11-17 2:50 UTC (permalink / raw)
To: git
With upcoming GCC 15, a new warning is added
(-Wunterminated-string-initialization) that fires when building git:
```
CC object-file.o
object-file.c:52:9: warning: initializer-string for array of ‘unsigned char’ is too long [-Wunterminated-string-initialization]
52 | "\x6e\xf1\x9b\x41\x22\x5c\x53\x69\xf1\xc1" \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
object-file.c:79:17: note: in expansion of macro ‘EMPTY_TREE_SHA256_BIN_LITERAL’
79 | .hash = EMPTY_TREE_SHA256_BIN_LITERAL,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
object-file.c:61:9: warning: initializer-string for array of ‘unsigned char’ is too long [-Wunterminated-string-initialization]
61 | "\x47\x3a\x0f\x4c\x3b\xe8\xa9\x36\x81\xa2" \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
object-file.c:83:17: note: in expansion of macro ‘EMPTY_BLOB_SHA256_BIN_LITERAL’
83 | .hash = EMPTY_BLOB_SHA256_BIN_LITERAL,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
Context for the new warning is at https://gcc.gnu.org/PR115185.
thanks,
sam
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: -Wunterminated-string-initialization warning with GCC 15 in object-file.c
2024-11-17 2:50 -Wunterminated-string-initialization warning with GCC 15 in object-file.c Sam James
@ 2024-11-17 9:03 ` Jeff King
2024-11-17 9:08 ` [PATCH 1/5] object-file: prefer array-of-bytes initializer for hash literals Jeff King
` (7 more replies)
0 siblings, 8 replies; 25+ messages in thread
From: Jeff King @ 2024-11-17 9:03 UTC (permalink / raw)
To: Sam James; +Cc: brian m. carlson, git
On Sun, Nov 17, 2024 at 02:50:39AM +0000, Sam James wrote:
> With upcoming GCC 15, a new warning is added
> (-Wunterminated-string-initialization) that fires when building git:
> ```
> CC object-file.o
> object-file.c:52:9: warning: initializer-string for array of ‘unsigned char’ is too long [-Wunterminated-string-initialization]
> 52 | "\x6e\xf1\x9b\x41\x22\x5c\x53\x69\xf1\xc1" \
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> object-file.c:79:17: note: in expansion of macro ‘EMPTY_TREE_SHA256_BIN_LITERAL’
> 79 | .hash = EMPTY_TREE_SHA256_BIN_LITERAL,
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> object-file.c:61:9: warning: initializer-string for array of ‘unsigned char’ is too long [-Wunterminated-string-initialization]
> 61 | "\x47\x3a\x0f\x4c\x3b\xe8\xa9\x36\x81\xa2" \
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> object-file.c:83:17: note: in expansion of macro ‘EMPTY_BLOB_SHA256_BIN_LITERAL’
> 83 | .hash = EMPTY_BLOB_SHA256_BIN_LITERAL,
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> ```
>
> Context for the new warning is at https://gcc.gnu.org/PR115185.
I think the warning is a false positive for us, but I don't begrudge
them for adding it. It could definitely catch real problems.
Here are some patches. The first one should fix the warning (but I don't
have gcc-15 handy to test!). Please let me know if it works for you (and
thank you for reporting).
The others are cleanups and future-proofing I found in the same area.
Not strictly required, but IMHO worth doing.
+cc brian since I think this is a continuation of some hash-algo
cleanups he did earlier, plus he piped up in the other gcc-15 thread. ;)
[1/5]: object-file: prefer array-of-bytes initializer for hash literals
[2/5]: object-file: drop confusing oid initializer of empty_tree struct
[3/5]: object-file: move empty_tree struct into find_cached_object()
[4/5]: object-file: drop oid field from find_cached_object() return value
[5/5]: object-file: inline empty tree and blob literals
object-file.c | 77 ++++++++++++++++++++++++---------------------------
1 file changed, 36 insertions(+), 41 deletions(-)
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 1/5] object-file: prefer array-of-bytes initializer for hash literals
2024-11-17 9:03 ` Jeff King
@ 2024-11-17 9:08 ` Jeff King
2024-11-17 9:52 ` René Scharfe
2024-11-17 9:08 ` [PATCH 2/5] object-file: drop confusing oid initializer of empty_tree struct Jeff King
` (6 subsequent siblings)
7 siblings, 1 reply; 25+ messages in thread
From: Jeff King @ 2024-11-17 9:08 UTC (permalink / raw)
To: Sam James; +Cc: brian m. carlson, git
We hard-code a few well-known hash values for empty trees and blobs in
both sha1 and sha256 formats. We do so with string literals like this:
#define EMPTY_TREE_SHA256_BIN_LITERAL \
"\x6e\xf1\x9b\x41\x22\x5c\x53\x69\xf1\xc1" \
"\x04\xd4\x5d\x8d\x85\xef\xa9\xb0\x57\xb5" \
"\x3b\x14\xb4\xb9\xb9\x39\xdd\x74\xde\xcc" \
"\x53\x21"
and then use it to initialize the hash field of an object_id struct.
That hash field is exactly 32 bytes long (the size we need for sha256).
But the string literal above is actually 33 bytes long due to the NUL
terminator. It's legal in C to initialize from a longer string literal;
the extra bytes are just ignored.
However, the upcoming gcc 15 will start warning about this:
CC object-file.o
object-file.c:52:9: warning: initializer-string for array of ‘unsigned char’ is too long [-Wunterminated-string-initialization]
52 | "\x6e\xf1\x9b\x41\x22\x5c\x53\x69\xf1\xc1" \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
object-file.c:79:17: note: in expansion of macro ‘EMPTY_TREE_SHA256_BIN_LITERAL’
which is understandable. Even though this is not a bug for us, since we
do not care about the NUL terminator (and are just using the literal as
a convenient format), it would be easy to accidentally create an array
that was mistakenly unterminated.
We can avoid this warning by switching the initializer to an actual
array of unsigned values. That arguably demonstrates our intent more
clearly anyway.
Reported-by: Sam James <sam@gentoo•org>
Signed-off-by: Jeff King <peff@peff•net>
---
I actually didn't find exact wording in the standard for using a
longer literal. But C99 section 6.7.8 (Initialization), para 32 shows
this exact case as "example 8".
You can view the diff with "--color-words --word-diff-regex=." to more
clearly see that the values themselves weren't changed.
object-file.c | 38 +++++++++++++++++++++-----------------
1 file changed, 21 insertions(+), 17 deletions(-)
diff --git a/object-file.c b/object-file.c
index b1a3463852..25ba54594b 100644
--- a/object-file.c
+++ b/object-file.c
@@ -45,23 +45,27 @@
#define MAX_HEADER_LEN 32
-#define EMPTY_TREE_SHA1_BIN_LITERAL \
- "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \
- "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04"
-#define EMPTY_TREE_SHA256_BIN_LITERAL \
- "\x6e\xf1\x9b\x41\x22\x5c\x53\x69\xf1\xc1" \
- "\x04\xd4\x5d\x8d\x85\xef\xa9\xb0\x57\xb5" \
- "\x3b\x14\xb4\xb9\xb9\x39\xdd\x74\xde\xcc" \
- "\x53\x21"
-
-#define EMPTY_BLOB_SHA1_BIN_LITERAL \
- "\xe6\x9d\xe2\x9b\xb2\xd1\xd6\x43\x4b\x8b" \
- "\x29\xae\x77\x5a\xd8\xc2\xe4\x8c\x53\x91"
-#define EMPTY_BLOB_SHA256_BIN_LITERAL \
- "\x47\x3a\x0f\x4c\x3b\xe8\xa9\x36\x81\xa2" \
- "\x67\xe3\xb1\xe9\xa7\xdc\xda\x11\x85\x43" \
- "\x6f\xe1\x41\xf7\x74\x91\x20\xa3\x03\x72" \
- "\x18\x13"
+#define EMPTY_TREE_SHA1_BIN_LITERAL { \
+ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, \
+ 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 \
+}
+#define EMPTY_TREE_SHA256_BIN_LITERAL { \
+ 0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1, \
+ 0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5, \
+ 0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc, \
+ 0x53, 0x21 \
+}
+
+#define EMPTY_BLOB_SHA1_BIN_LITERAL { \
+ 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b, \
+ 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 \
+}
+#define EMPTY_BLOB_SHA256_BIN_LITERAL { \
+ 0x47, 0x3a, 0x0f, 0x4c, 0x3b, 0xe8, 0xa9, 0x36, 0x81, 0xa2, \
+ 0x67, 0xe3, 0xb1, 0xe9, 0xa7, 0xdc, 0xda, 0x11, 0x85, 0x43, \
+ 0x6f, 0xe1, 0x41, 0xf7, 0x74, 0x91, 0x20, 0xa3, 0x03, 0x72, \
+ 0x18, 0x13 \
+}
static const struct object_id empty_tree_oid = {
.hash = EMPTY_TREE_SHA1_BIN_LITERAL,
--
2.47.0.541.ge258d9a1f8
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 2/5] object-file: drop confusing oid initializer of empty_tree struct
2024-11-17 9:03 ` Jeff King
2024-11-17 9:08 ` [PATCH 1/5] object-file: prefer array-of-bytes initializer for hash literals Jeff King
@ 2024-11-17 9:08 ` Jeff King
2024-11-17 9:08 ` [PATCH 3/5] object-file: move empty_tree struct into find_cached_object() Jeff King
` (5 subsequent siblings)
7 siblings, 0 replies; 25+ messages in thread
From: Jeff King @ 2024-11-17 9:08 UTC (permalink / raw)
To: Sam James; +Cc: brian m. carlson, git
We treat the empty tree specially, providing an in-memory "cached" copy,
which allows you to diff against it even if the object doesn't exist in
the repository. This is implemented as part of the larger cached_object
subsystem, but we use a stand-alone empty_tree struct.
We initialize the oid of that struct using EMPTY_TREE_SHA1_BIN_LITERAL.
At first glance, that seems like a bug; how could this ever work for
sha256 repositories?
The answer is that we never look at the oid field! The oid field is used
to look up entries added by pretend_object_file() to the cached_objects
array. But for our stand-alone entry, we look for it independently using
the_hash_algo->empty_tree, which will point to the correct algo struct
for the repository.
This happened in 62ba93eaa9 (sha1_file: convert cached object code to
struct object_id, 2018-05-02), which even mentions that this field is
never used. Let's reduce confusion for anybody reading this code by
replacing the sha1 initializer with a comment. The resulting field will
be all-zeroes, so any violation of our assumption that the oid field is
not used will break equally for sha1 and sha256.
Signed-off-by: Jeff King <peff@peff•net>
---
object-file.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/object-file.c b/object-file.c
index 25ba54594b..b7c4fdcabd 100644
--- a/object-file.c
+++ b/object-file.c
@@ -326,9 +326,7 @@ static struct cached_object {
static int cached_object_nr, cached_object_alloc;
static struct cached_object empty_tree = {
- .oid = {
- .hash = EMPTY_TREE_SHA1_BIN_LITERAL,
- },
+ /* no oid needed; we'll look it up manually based on the_hash_algo */
.type = OBJ_TREE,
.buf = "",
};
--
2.47.0.541.ge258d9a1f8
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 3/5] object-file: move empty_tree struct into find_cached_object()
2024-11-17 9:03 ` Jeff King
2024-11-17 9:08 ` [PATCH 1/5] object-file: prefer array-of-bytes initializer for hash literals Jeff King
2024-11-17 9:08 ` [PATCH 2/5] object-file: drop confusing oid initializer of empty_tree struct Jeff King
@ 2024-11-17 9:08 ` Jeff King
2024-11-18 7:40 ` Patrick Steinhardt
2024-11-17 9:10 ` [PATCH 4/5] object-file: drop oid field from find_cached_object() return value Jeff King
` (4 subsequent siblings)
7 siblings, 1 reply; 25+ messages in thread
From: Jeff King @ 2024-11-17 9:08 UTC (permalink / raw)
To: Sam James; +Cc: brian m. carlson, git
The fake empty_tree struct is a static global, but the only code that
looks at it is find_cached_object(). The struct itself is a little odd,
with an invalid "oid" field that is handled specially by that function.
Since it's really just an implementation detail, let's move it to a
static within the function. That future-proofs against other code trying
to use it and seeing the weird oid value.
Signed-off-by: Jeff King <peff@peff•net>
---
object-file.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/object-file.c b/object-file.c
index b7c4fdcabd..5fadd470c1 100644
--- a/object-file.c
+++ b/object-file.c
@@ -325,14 +325,13 @@ static struct cached_object {
} *cached_objects;
static int cached_object_nr, cached_object_alloc;
-static struct cached_object empty_tree = {
- /* no oid needed; we'll look it up manually based on the_hash_algo */
- .type = OBJ_TREE,
- .buf = "",
-};
-
static struct cached_object *find_cached_object(const struct object_id *oid)
{
+ static struct cached_object empty_tree = {
+ /* no oid needed; we'll look it up manually based on the_hash_algo */
+ .type = OBJ_TREE,
+ .buf = "",
+ };
int i;
struct cached_object *co = cached_objects;
--
2.47.0.541.ge258d9a1f8
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 4/5] object-file: drop oid field from find_cached_object() return value
2024-11-17 9:03 ` Jeff King
` (2 preceding siblings ...)
2024-11-17 9:08 ` [PATCH 3/5] object-file: move empty_tree struct into find_cached_object() Jeff King
@ 2024-11-17 9:10 ` Jeff King
2024-11-17 9:14 ` [PATCH 5/5] object-file: inline empty tree and blob literals Jeff King
` (3 subsequent siblings)
7 siblings, 0 replies; 25+ messages in thread
From: Jeff King @ 2024-11-17 9:10 UTC (permalink / raw)
To: Sam James; +Cc: brian m. carlson, git
The pretend_object_file() function adds to an array mapping oids to
object contents, which are later retrieved with find_cached_object().
We naturally need to store the oid for each entry, since it's the lookup
key.
But find_cached_object() also returns a hard-coded empty_tree object.
There we don't care about its oid field and instead compare against
the_hash_algo->empty_tree. The oid field is left as all-zeroes.
This all works, but it means that the cached_object struct we return
from find_cached_object() may or may not have a valid oid field, depend
whether it is the hard-coded tree or came from pretend_object_file().
Nobody looks at the field, so there's no bug. But let's future-proof it
by returning only the object contents themselves, not the oid. We'll
continue to call this "struct cached_object", and the array entry
mapping the key to those contents will be a "cached_object_entry".
This would also let us swap out the array for a better data structure
(like a hashmap) if we chose, but there's not much point. The only code
that adds an entry is git-blame, which adds at most a single entry per
process.
Signed-off-by: Jeff King <peff@peff•net>
---
object-file.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/object-file.c b/object-file.c
index 5fadd470c1..e461e351ca 100644
--- a/object-file.c
+++ b/object-file.c
@@ -317,27 +317,28 @@ int hash_algo_by_length(int len)
* to write them into the object store (e.g. a browse-only
* application).
*/
-static struct cached_object {
+static struct cached_object_entry {
struct object_id oid;
- enum object_type type;
- const void *buf;
- unsigned long size;
+ struct cached_object {
+ enum object_type type;
+ const void *buf;
+ unsigned long size;
+ } value;
} *cached_objects;
static int cached_object_nr, cached_object_alloc;
static struct cached_object *find_cached_object(const struct object_id *oid)
{
static struct cached_object empty_tree = {
- /* no oid needed; we'll look it up manually based on the_hash_algo */
.type = OBJ_TREE,
.buf = "",
};
int i;
- struct cached_object *co = cached_objects;
+ struct cached_object_entry *co = cached_objects;
for (i = 0; i < cached_object_nr; i++, co++) {
if (oideq(&co->oid, oid))
- return co;
+ return &co->value;
}
if (oideq(oid, the_hash_algo->empty_tree))
return &empty_tree;
@@ -1850,7 +1851,7 @@ int oid_object_info(struct repository *r,
int pretend_object_file(void *buf, unsigned long len, enum object_type type,
struct object_id *oid)
{
- struct cached_object *co;
+ struct cached_object_entry *co;
char *co_buf;
hash_object_file(the_hash_algo, buf, len, type, oid);
@@ -1859,11 +1860,11 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type,
return 0;
ALLOC_GROW(cached_objects, cached_object_nr + 1, cached_object_alloc);
co = &cached_objects[cached_object_nr++];
- co->size = len;
- co->type = type;
+ co->value.size = len;
+ co->value.type = type;
co_buf = xmalloc(len);
memcpy(co_buf, buf, len);
- co->buf = co_buf;
+ co->value.buf = co_buf;
oidcpy(&co->oid, oid);
return 0;
}
--
2.47.0.541.ge258d9a1f8
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 5/5] object-file: inline empty tree and blob literals
2024-11-17 9:03 ` Jeff King
` (3 preceding siblings ...)
2024-11-17 9:10 ` [PATCH 4/5] object-file: drop oid field from find_cached_object() return value Jeff King
@ 2024-11-17 9:14 ` Jeff King
2024-11-18 7:40 ` Patrick Steinhardt
2024-11-17 16:03 ` -Wunterminated-string-initialization warning with GCC 15 in object-file.c brian m. carlson
` (2 subsequent siblings)
7 siblings, 1 reply; 25+ messages in thread
From: Jeff King @ 2024-11-17 9:14 UTC (permalink / raw)
To: Sam James; +Cc: brian m. carlson, git
We define macros with the bytes of the empty trees and blobs for sha1
and sha256. But since e1ccd7e2b1 (sha1_file: only expose empty object
constants through git_hash_algo, 2018-05-02), those are used only for
initializing the git_hash_algo entries. Any other code using the macros
directly would be suspicious, since a hash_algo pointer is the level of
indirection we use to make everything work with both sha1 and sha256.
So let's future proof against code doing the wrong thing by dropping the
macros entirely and just initializing the structs directly.
Signed-off-by: Jeff King <peff@peff•net>
---
Sadly you can't use --word-diff to make sense of this one, and
--color-moved is foiled by dropping the trailing backslashes. Anybody is
welcome to verify that the values did not change. :)
We're still left with split-out structs for empty_tree_oid_sha256, etc
(and confusingly the sha1 ones do not even say "sha1"). I think we could
take this all one step further and inline those directly into the
git_hash_algo. But that would have repercussions throughout the tree,
since many spots would switch from:
repo->hash_algo->empty_tree
to:
&repo->hash_algo->empty_tree
Not sure if it's worth it (it's also one less pointer chase, but I kind
of doubt that accessing the empty tree oid is ever a hot code path).
object-file.c | 47 ++++++++++++++++++++---------------------------
1 file changed, 20 insertions(+), 27 deletions(-)
diff --git a/object-file.c b/object-file.c
index e461e351ca..e325a52be5 100644
--- a/object-file.c
+++ b/object-file.c
@@ -44,47 +44,40 @@
/* The maximum size for an object header. */
#define MAX_HEADER_LEN 32
-
-#define EMPTY_TREE_SHA1_BIN_LITERAL { \
- 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, \
- 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 \
-}
-#define EMPTY_TREE_SHA256_BIN_LITERAL { \
- 0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1, \
- 0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5, \
- 0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc, \
- 0x53, 0x21 \
-}
-
-#define EMPTY_BLOB_SHA1_BIN_LITERAL { \
- 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b, \
- 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 \
-}
-#define EMPTY_BLOB_SHA256_BIN_LITERAL { \
- 0x47, 0x3a, 0x0f, 0x4c, 0x3b, 0xe8, 0xa9, 0x36, 0x81, 0xa2, \
- 0x67, 0xe3, 0xb1, 0xe9, 0xa7, 0xdc, 0xda, 0x11, 0x85, 0x43, \
- 0x6f, 0xe1, 0x41, 0xf7, 0x74, 0x91, 0x20, 0xa3, 0x03, 0x72, \
- 0x18, 0x13 \
-}
-
static const struct object_id empty_tree_oid = {
- .hash = EMPTY_TREE_SHA1_BIN_LITERAL,
+ .hash ={
+ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60,
+ 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04
+ },
.algo = GIT_HASH_SHA1,
};
static const struct object_id empty_blob_oid = {
- .hash = EMPTY_BLOB_SHA1_BIN_LITERAL,
+ .hash = {
+ 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b,
+ 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91
+ },
.algo = GIT_HASH_SHA1,
};
static const struct object_id null_oid_sha1 = {
.hash = {0},
.algo = GIT_HASH_SHA1,
};
static const struct object_id empty_tree_oid_sha256 = {
- .hash = EMPTY_TREE_SHA256_BIN_LITERAL,
+ .hash = {
+ 0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1,
+ 0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5,
+ 0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc,
+ 0x53, 0x21
+ },
.algo = GIT_HASH_SHA256,
};
static const struct object_id empty_blob_oid_sha256 = {
- .hash = EMPTY_BLOB_SHA256_BIN_LITERAL,
+ .hash = {
+ 0x47, 0x3a, 0x0f, 0x4c, 0x3b, 0xe8, 0xa9, 0x36, 0x81, 0xa2,
+ 0x67, 0xe3, 0xb1, 0xe9, 0xa7, 0xdc, 0xda, 0x11, 0x85, 0x43,
+ 0x6f, 0xe1, 0x41, 0xf7, 0x74, 0x91, 0x20, 0xa3, 0x03, 0x72,
+ 0x18, 0x13
+ },
.algo = GIT_HASH_SHA256,
};
static const struct object_id null_oid_sha256 = {
--
2.47.0.541.ge258d9a1f8
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH 1/5] object-file: prefer array-of-bytes initializer for hash literals
2024-11-17 9:08 ` [PATCH 1/5] object-file: prefer array-of-bytes initializer for hash literals Jeff King
@ 2024-11-17 9:52 ` René Scharfe
2024-11-18 9:06 ` Jeff King
0 siblings, 1 reply; 25+ messages in thread
From: René Scharfe @ 2024-11-17 9:52 UTC (permalink / raw)
To: Jeff King, Sam James; +Cc: brian m. carlson, git
Am 17.11.24 um 10:08 schrieb Jeff King:
> We hard-code a few well-known hash values for empty trees and blobs in
> both sha1 and sha256 formats. We do so with string literals like this:
>
> #define EMPTY_TREE_SHA256_BIN_LITERAL \
> "\x6e\xf1\x9b\x41\x22\x5c\x53\x69\xf1\xc1" \
> "\x04\xd4\x5d\x8d\x85\xef\xa9\xb0\x57\xb5" \
> "\x3b\x14\xb4\xb9\xb9\x39\xdd\x74\xde\xcc" \
> "\x53\x21"
>
> and then use it to initialize the hash field of an object_id struct.
> That hash field is exactly 32 bytes long (the size we need for sha256).
> But the string literal above is actually 33 bytes long due to the NUL
> terminator. It's legal in C to initialize from a longer string literal;
> the extra bytes are just ignored.
>
> However, the upcoming gcc 15 will start warning about this:
>
> CC object-file.o
> object-file.c:52:9: warning: initializer-string for array of ‘unsigned char’ is too long [-Wunterminated-string-initialization]
> 52 | "\x6e\xf1\x9b\x41\x22\x5c\x53\x69\xf1\xc1" \
> | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> object-file.c:79:17: note: in expansion of macro ‘EMPTY_TREE_SHA256_BIN_LITERAL’
>
> which is understandable. Even though this is not a bug for us, since we
> do not care about the NUL terminator (and are just using the literal as
> a convenient format), it would be easy to accidentally create an array
> that was mistakenly unterminated.
>
> We can avoid this warning by switching the initializer to an actual
> array of unsigned values. That arguably demonstrates our intent more
> clearly anyway.
OK.
> Reported-by: Sam James <sam@gentoo•org>
> Signed-off-by: Jeff King <peff@peff•net>
> ---
> I actually didn't find exact wording in the standard for using a
> longer literal. But C99 section 6.7.8 (Initialization), para 32 shows
> this exact case as "example 8".
>
> You can view the diff with "--color-words --word-diff-regex=." to more
> clearly see that the values themselves weren't changed.
>
> object-file.c | 38 +++++++++++++++++++++-----------------
> 1 file changed, 21 insertions(+), 17 deletions(-)
>
> diff --git a/object-file.c b/object-file.c
> index b1a3463852..25ba54594b 100644
> --- a/object-file.c
> +++ b/object-file.c
> @@ -45,23 +45,27 @@
> #define MAX_HEADER_LEN 32
>
>
> -#define EMPTY_TREE_SHA1_BIN_LITERAL \
> - "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \
> - "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04"
> -#define EMPTY_TREE_SHA256_BIN_LITERAL \
> - "\x6e\xf1\x9b\x41\x22\x5c\x53\x69\xf1\xc1" \
> - "\x04\xd4\x5d\x8d\x85\xef\xa9\xb0\x57\xb5" \
> - "\x3b\x14\xb4\xb9\xb9\x39\xdd\x74\xde\xcc" \
> - "\x53\x21"
> -
> -#define EMPTY_BLOB_SHA1_BIN_LITERAL \
> - "\xe6\x9d\xe2\x9b\xb2\xd1\xd6\x43\x4b\x8b" \
> - "\x29\xae\x77\x5a\xd8\xc2\xe4\x8c\x53\x91"
> -#define EMPTY_BLOB_SHA256_BIN_LITERAL \
> - "\x47\x3a\x0f\x4c\x3b\xe8\xa9\x36\x81\xa2" \
> - "\x67\xe3\xb1\xe9\xa7\xdc\xda\x11\x85\x43" \
> - "\x6f\xe1\x41\xf7\x74\x91\x20\xa3\x03\x72" \
> - "\x18\x13"
> +#define EMPTY_TREE_SHA1_BIN_LITERAL { \
> + 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, \
> + 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 \
The added space at the beginning looks seems unintended.
The two spaces before the backslash look odd. One space, one tab or
lining up the backslashes with spaces would look better.
Patch 5 does away with those spaces, thankfully. :)
> +}
> +#define EMPTY_TREE_SHA256_BIN_LITERAL { \
> + 0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1, \
> + 0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5, \
> + 0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc, \
> + 0x53, 0x21 \
> +}
> +
> +#define EMPTY_BLOB_SHA1_BIN_LITERAL { \
> + 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b, \
> + 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 \
> +}
> +#define EMPTY_BLOB_SHA256_BIN_LITERAL { \
> + 0x47, 0x3a, 0x0f, 0x4c, 0x3b, 0xe8, 0xa9, 0x36, 0x81, 0xa2, \
> + 0x67, 0xe3, 0xb1, 0xe9, 0xa7, 0xdc, 0xda, 0x11, 0x85, 0x43, \
> + 0x6f, 0xe1, 0x41, 0xf7, 0x74, 0x91, 0x20, 0xa3, 0x03, 0x72, \
> + 0x18, 0x13 \
> +}
>
> static const struct object_id empty_tree_oid = {
> .hash = EMPTY_TREE_SHA1_BIN_LITERAL,
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: -Wunterminated-string-initialization warning with GCC 15 in object-file.c
2024-11-17 9:03 ` Jeff King
` (4 preceding siblings ...)
2024-11-17 9:14 ` [PATCH 5/5] object-file: inline empty tree and blob literals Jeff King
@ 2024-11-17 16:03 ` brian m. carlson
2024-11-18 9:19 ` Jeff King
2024-11-18 7:40 ` Patrick Steinhardt
2024-11-18 9:54 ` [PATCH 0/6] -Wunterminated-string-initialization warning + cleanups Jeff King
7 siblings, 1 reply; 25+ messages in thread
From: brian m. carlson @ 2024-11-17 16:03 UTC (permalink / raw)
To: Jeff King; +Cc: Sam James, git
[-- Attachment #1: Type: text/plain, Size: 828 bytes --]
On 2024-11-17 at 09:03:29, Jeff King wrote:
> Here are some patches. The first one should fix the warning (but I don't
> have gcc-15 handy to test!). Please let me know if it works for you (and
> thank you for reporting).
Just so you know, since I believe you also use Debian unstable, you can
install the gcc-snapshot package (which is, admittedly, rather large)
and use `CC=/usr/lib/gcc-snapshot/bin/gcc`.
> The others are cleanups and future-proofing I found in the same area.
> Not strictly required, but IMHO worth doing.
>
> +cc brian since I think this is a continuation of some hash-algo
> cleanups he did earlier, plus he piped up in the other gcc-15 thread. ;)
Other than the issue that René noticed, this seems reasonable to me.
--
brian m. carlson (they/them or he/him)
Toronto, Ontario, CA
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 262 bytes --]
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 3/5] object-file: move empty_tree struct into find_cached_object()
2024-11-17 9:08 ` [PATCH 3/5] object-file: move empty_tree struct into find_cached_object() Jeff King
@ 2024-11-18 7:40 ` Patrick Steinhardt
2024-11-18 9:17 ` Jeff King
0 siblings, 1 reply; 25+ messages in thread
From: Patrick Steinhardt @ 2024-11-18 7:40 UTC (permalink / raw)
To: Jeff King; +Cc: Sam James, brian m. carlson, git
On Sun, Nov 17, 2024 at 04:08:42AM -0500, Jeff King wrote:
> diff --git a/object-file.c b/object-file.c
> index b7c4fdcabd..5fadd470c1 100644
> --- a/object-file.c
> +++ b/object-file.c
> @@ -325,14 +325,13 @@ static struct cached_object {
> } *cached_objects;
> static int cached_object_nr, cached_object_alloc;
>
> -static struct cached_object empty_tree = {
> - /* no oid needed; we'll look it up manually based on the_hash_algo */
> - .type = OBJ_TREE,
> - .buf = "",
> -};
> -
> static struct cached_object *find_cached_object(const struct object_id *oid)
> {
> + static struct cached_object empty_tree = {
> + /* no oid needed; we'll look it up manually based on the_hash_algo */
> + .type = OBJ_TREE,
> + .buf = "",
> + };
> int i;
> struct cached_object *co = cached_objects;
I was wondering whether we want to also mark this as `const` so that no
caller ever gets the idea of modifying the struct. Something like the
below patch (which applies on "master", so it of course would have to
adapt to your changes).
Patrick
diff --git a/object-file.c b/object-file.c
index b1a3463852..f15a3f6a5f 100644
--- a/object-file.c
+++ b/object-file.c
@@ -321,7 +321,7 @@ static struct cached_object {
} *cached_objects;
static int cached_object_nr, cached_object_alloc;
-static struct cached_object empty_tree = {
+static const struct cached_object empty_tree = {
.oid = {
.hash = EMPTY_TREE_SHA1_BIN_LITERAL,
},
@@ -329,7 +329,7 @@ static struct cached_object empty_tree = {
.buf = "",
};
-static struct cached_object *find_cached_object(const struct object_id *oid)
+static const struct cached_object *find_cached_object(const struct object_id *oid)
{
int i;
struct cached_object *co = cached_objects;
@@ -1627,7 +1627,7 @@ static int do_oid_object_info_extended(struct repository *r,
struct object_info *oi, unsigned flags)
{
static struct object_info blank_oi = OBJECT_INFO_INIT;
- struct cached_object *co;
+ const struct cached_object *co;
struct pack_entry e;
int rtype;
const struct object_id *real = oid;
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: [PATCH 5/5] object-file: inline empty tree and blob literals
2024-11-17 9:14 ` [PATCH 5/5] object-file: inline empty tree and blob literals Jeff King
@ 2024-11-18 7:40 ` Patrick Steinhardt
0 siblings, 0 replies; 25+ messages in thread
From: Patrick Steinhardt @ 2024-11-18 7:40 UTC (permalink / raw)
To: Jeff King; +Cc: Sam James, brian m. carlson, git
On Sun, Nov 17, 2024 at 04:14:23AM -0500, Jeff King wrote:
> static const struct object_id empty_tree_oid = {
> - .hash = EMPTY_TREE_SHA1_BIN_LITERAL,
> + .hash ={
There's a missing space here.
Patrick
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: -Wunterminated-string-initialization warning with GCC 15 in object-file.c
2024-11-17 9:03 ` Jeff King
` (5 preceding siblings ...)
2024-11-17 16:03 ` -Wunterminated-string-initialization warning with GCC 15 in object-file.c brian m. carlson
@ 2024-11-18 7:40 ` Patrick Steinhardt
2024-11-18 9:54 ` [PATCH 0/6] -Wunterminated-string-initialization warning + cleanups Jeff King
7 siblings, 0 replies; 25+ messages in thread
From: Patrick Steinhardt @ 2024-11-18 7:40 UTC (permalink / raw)
To: Jeff King; +Cc: Sam James, brian m. carlson, git
On Sun, Nov 17, 2024 at 04:03:29AM -0500, Jeff King wrote:
> On Sun, Nov 17, 2024 at 02:50:39AM +0000, Sam James wrote:
>
> > With upcoming GCC 15, a new warning is added
> > (-Wunterminated-string-initialization) that fires when building git:
> > ```
> > CC object-file.o
> > object-file.c:52:9: warning: initializer-string for array of ‘unsigned char’ is too long [-Wunterminated-string-initialization]
> > 52 | "\x6e\xf1\x9b\x41\x22\x5c\x53\x69\xf1\xc1" \
> > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > object-file.c:79:17: note: in expansion of macro ‘EMPTY_TREE_SHA256_BIN_LITERAL’
> > 79 | .hash = EMPTY_TREE_SHA256_BIN_LITERAL,
> > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > object-file.c:61:9: warning: initializer-string for array of ‘unsigned char’ is too long [-Wunterminated-string-initialization]
> > 61 | "\x47\x3a\x0f\x4c\x3b\xe8\xa9\x36\x81\xa2" \
> > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > object-file.c:83:17: note: in expansion of macro ‘EMPTY_BLOB_SHA256_BIN_LITERAL’
> > 83 | .hash = EMPTY_BLOB_SHA256_BIN_LITERAL,
> > | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > ```
> >
> > Context for the new warning is at https://gcc.gnu.org/PR115185.
>
> I think the warning is a false positive for us, but I don't begrudge
> them for adding it. It could definitely catch real problems.
>
> Here are some patches. The first one should fix the warning (but I don't
> have gcc-15 handy to test!). Please let me know if it works for you (and
> thank you for reporting).
>
> The others are cleanups and future-proofing I found in the same area.
> Not strictly required, but IMHO worth doing.
>
> +cc brian since I think this is a continuation of some hash-algo
> cleanups he did earlier, plus he piped up in the other gcc-15 thread. ;)
I've got two comments, but other than that this looks like a nice
cleanup to me. Thanks!
Patrick
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 1/5] object-file: prefer array-of-bytes initializer for hash literals
2024-11-17 9:52 ` René Scharfe
@ 2024-11-18 9:06 ` Jeff King
0 siblings, 0 replies; 25+ messages in thread
From: Jeff King @ 2024-11-18 9:06 UTC (permalink / raw)
To: René Scharfe; +Cc: Sam James, brian m. carlson, git
On Sun, Nov 17, 2024 at 10:52:40AM +0100, René Scharfe wrote:
> > -#define EMPTY_BLOB_SHA256_BIN_LITERAL \
> > - "\x47\x3a\x0f\x4c\x3b\xe8\xa9\x36\x81\xa2" \
> > - "\x67\xe3\xb1\xe9\xa7\xdc\xda\x11\x85\x43" \
> > - "\x6f\xe1\x41\xf7\x74\x91\x20\xa3\x03\x72" \
> > - "\x18\x13"
> > +#define EMPTY_TREE_SHA1_BIN_LITERAL { \
> > + 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, \
> > + 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 \
>
> The added space at the beginning looks seems unintended.
That was from the original, which had a tab followed by a space (maybe
to line up with the "E" in "EMPTY"?). I did s/"// and s/\\x\(..\)/0x\1, /
which left it.
> The two spaces before the backslash look odd. One space, one tab or
> lining up the backslashes with spaces would look better.
This one is my fault, though. My regex left an extra comma at the end,
which I somehow managed to bungle removing. ;)
> Patch 5 does away with those spaces, thankfully. :)
Yep. Looks like there might be some whitespace oddities left over,
though, so I'll fix this on re-roll.
Thanks.
-Peff
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 3/5] object-file: move empty_tree struct into find_cached_object()
2024-11-18 7:40 ` Patrick Steinhardt
@ 2024-11-18 9:17 ` Jeff King
0 siblings, 0 replies; 25+ messages in thread
From: Jeff King @ 2024-11-18 9:17 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: Sam James, brian m. carlson, git
On Mon, Nov 18, 2024 at 08:40:34AM +0100, Patrick Steinhardt wrote:
> > static struct cached_object *find_cached_object(const struct object_id *oid)
> > {
> > + static struct cached_object empty_tree = {
> > + /* no oid needed; we'll look it up manually based on the_hash_algo */
> > + .type = OBJ_TREE,
> > + .buf = "",
> > + };
> > int i;
> > struct cached_object *co = cached_objects;
>
> I was wondering whether we want to also mark this as `const` so that no
> caller ever gets the idea of modifying the struct. Something like the
> below patch (which applies on "master", so it of course would have to
> adapt to your changes).
This seems like a fairly unlikely bug to me, just because it would be
weird for somebody to want to write to the response (whereas the other
future-proofing was against somebody reading a private-ish value).
Still, I agree that "const" is the right thing, and it's not hard to add
it in to my series.
> diff --git a/object-file.c b/object-file.c
> index b1a3463852..f15a3f6a5f 100644
> --- a/object-file.c
> +++ b/object-file.c
> @@ -321,7 +321,7 @@ static struct cached_object {
> } *cached_objects;
> static int cached_object_nr, cached_object_alloc;
>
> -static struct cached_object empty_tree = {
> +static const struct cached_object empty_tree = {
> .oid = {
> .hash = EMPTY_TREE_SHA1_BIN_LITERAL,
> },
This hunk is technically not needed since we can implicitly cast from
non-const to const when returning. I included it, though, along with
making the iteration pointer in find_cached_object() const since that
better represents the intent.
-Peff
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: -Wunterminated-string-initialization warning with GCC 15 in object-file.c
2024-11-17 16:03 ` -Wunterminated-string-initialization warning with GCC 15 in object-file.c brian m. carlson
@ 2024-11-18 9:19 ` Jeff King
2024-11-18 9:58 ` Sam James
0 siblings, 1 reply; 25+ messages in thread
From: Jeff King @ 2024-11-18 9:19 UTC (permalink / raw)
To: brian m. carlson; +Cc: Sam James, git
On Sun, Nov 17, 2024 at 04:03:31PM +0000, brian m. carlson wrote:
> On 2024-11-17 at 09:03:29, Jeff King wrote:
> > Here are some patches. The first one should fix the warning (but I don't
> > have gcc-15 handy to test!). Please let me know if it works for you (and
> > thank you for reporting).
>
> Just so you know, since I believe you also use Debian unstable, you can
> install the gcc-snapshot package (which is, admittedly, rather large)
> and use `CC=/usr/lib/gcc-snapshot/bin/gcc`.
Thanks, I was stupidly looking for a "gcc-15" package in experimental,
not realizing it had not actually been released yet. I reproduced the
problem with the snapshot (which is from 20241004) and verified that my
series fixes it.
-Peff
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 0/6] -Wunterminated-string-initialization warning + cleanups
2024-11-17 9:03 ` Jeff King
` (6 preceding siblings ...)
2024-11-18 7:40 ` Patrick Steinhardt
@ 2024-11-18 9:54 ` Jeff King
2024-11-18 9:54 ` [PATCH 1/6] object-file: prefer array-of-bytes initializer for hash literals Jeff King
` (6 more replies)
7 siblings, 7 replies; 25+ messages in thread
From: Jeff King @ 2024-11-18 9:54 UTC (permalink / raw)
To: Sam James
Cc: René Scharfe, Patrick Steinhardt, Chris Torek,
brian m. carlson, git
> Here are some patches. The first one should fix the warning (but I don't
> have gcc-15 handy to test!). Please let me know if it works for you (and
> thank you for reporting).
And here's a minor re-roll from comments on the list. I was able to
reproduce and test myself this time; the patch indeed fixes the problem.
Changes from v1:
- add more standards explanation to the first commit (thanks for
pointers from Chris Torek off-list)
- fixes small whitespace issues in patches 1 and 6
- new patch (5) to add "const" as appropriate
[1/6]: object-file: prefer array-of-bytes initializer for hash literals
[2/6]: object-file: drop confusing oid initializer of empty_tree struct
[3/6]: object-file: move empty_tree struct into find_cached_object()
[4/6]: object-file: drop oid field from find_cached_object() return value
[5/6]: object-file: treat cached_object values as const
[6/6]: object-file: inline empty tree and blob literals
object-file.c | 81 ++++++++++++++++++++++++---------------------------
1 file changed, 38 insertions(+), 43 deletions(-)
1: da69342eba ! 1: ec76b9eebb object-file: prefer array-of-bytes initializer for hash literals
@@ Commit message
and then use it to initialize the hash field of an object_id struct.
That hash field is exactly 32 bytes long (the size we need for sha256).
But the string literal above is actually 33 bytes long due to the NUL
- terminator. It's legal in C to initialize from a longer string literal;
- the extra bytes are just ignored.
+ terminator. This is legal in C, and the NUL is ignored.
- However, the upcoming gcc 15 will start warning about this:
+ Side note on legality: in general excess initializer elements are
+ forbidden, and gcc will warn on both of these:
+
+ char foo[3] = { 'h', 'u', 'g', 'e' };
+ char bar[3] = "VeryLongString";
+
+ I couldn't find specific language in the standard allowing
+ initialization from a string literal where _just_ the NUL is ignored,
+ but C99 section 6.7.8 (Initialization), paragraph 32 shows this exact
+ case as "example 8".
+
+ However, the upcoming gcc 15 will start warning for this case (when
+ compiled with -Wextra via DEVELOPER=1):
CC object-file.o
object-file.c:52:9: warning: initializer-string for array of ‘unsigned char’ is too long [-Wunterminated-string-initialization]
@@ object-file.c
- "\x6f\xe1\x41\xf7\x74\x91\x20\xa3\x03\x72" \
- "\x18\x13"
+#define EMPTY_TREE_SHA1_BIN_LITERAL { \
-+ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, \
-+ 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 \
++ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, \
++ 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 \
+}
+#define EMPTY_TREE_SHA256_BIN_LITERAL { \
-+ 0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1, \
-+ 0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5, \
-+ 0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc, \
++ 0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1, \
++ 0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5, \
++ 0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc, \
+ 0x53, 0x21 \
+}
+
+#define EMPTY_BLOB_SHA1_BIN_LITERAL { \
-+ 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b, \
++ 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b, \
+ 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 \
+}
+#define EMPTY_BLOB_SHA256_BIN_LITERAL { \
-+ 0x47, 0x3a, 0x0f, 0x4c, 0x3b, 0xe8, 0xa9, 0x36, 0x81, 0xa2, \
-+ 0x67, 0xe3, 0xb1, 0xe9, 0xa7, 0xdc, 0xda, 0x11, 0x85, 0x43, \
-+ 0x6f, 0xe1, 0x41, 0xf7, 0x74, 0x91, 0x20, 0xa3, 0x03, 0x72, \
++ 0x47, 0x3a, 0x0f, 0x4c, 0x3b, 0xe8, 0xa9, 0x36, 0x81, 0xa2, \
++ 0x67, 0xe3, 0xb1, 0xe9, 0xa7, 0xdc, 0xda, 0x11, 0x85, 0x43, \
++ 0x6f, 0xe1, 0x41, 0xf7, 0x74, 0x91, 0x20, 0xa3, 0x03, 0x72, \
+ 0x18, 0x13 \
+}
2: b8416b33d2 = 2: 0beaf2d65e object-file: drop confusing oid initializer of empty_tree struct
3: 8f5a9f5e30 = 3: d0c28cb1c9 object-file: move empty_tree struct into find_cached_object()
4: e2d0c9b56d = 4: 551e5938d5 object-file: drop oid field from find_cached_object() return value
-: ---------- > 5: d5641358a2 object-file: treat cached_object values as const
5: 7ebc8d2d2c ! 6: 82c43bfc78 object-file: inline empty tree and blob literals
@@ object-file.c
-
-#define EMPTY_TREE_SHA1_BIN_LITERAL { \
-- 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, \
-- 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 \
+- 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, \
+- 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 \
-}
-#define EMPTY_TREE_SHA256_BIN_LITERAL { \
-- 0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1, \
-- 0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5, \
-- 0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc, \
+- 0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1, \
+- 0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5, \
+- 0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc, \
- 0x53, 0x21 \
-}
-
-#define EMPTY_BLOB_SHA1_BIN_LITERAL { \
-- 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b, \
+- 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b, \
- 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 \
-}
-#define EMPTY_BLOB_SHA256_BIN_LITERAL { \
-- 0x47, 0x3a, 0x0f, 0x4c, 0x3b, 0xe8, 0xa9, 0x36, 0x81, 0xa2, \
-- 0x67, 0xe3, 0xb1, 0xe9, 0xa7, 0xdc, 0xda, 0x11, 0x85, 0x43, \
-- 0x6f, 0xe1, 0x41, 0xf7, 0x74, 0x91, 0x20, 0xa3, 0x03, 0x72, \
+- 0x47, 0x3a, 0x0f, 0x4c, 0x3b, 0xe8, 0xa9, 0x36, 0x81, 0xa2, \
+- 0x67, 0xe3, 0xb1, 0xe9, 0xa7, 0xdc, 0xda, 0x11, 0x85, 0x43, \
+- 0x6f, 0xe1, 0x41, 0xf7, 0x74, 0x91, 0x20, 0xa3, 0x03, 0x72, \
- 0x18, 0x13 \
-}
-
static const struct object_id empty_tree_oid = {
- .hash = EMPTY_TREE_SHA1_BIN_LITERAL,
-+ .hash ={
++ .hash = {
+ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60,
+ 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04
+ },
^ permalink raw reply [flat|nested] 25+ messages in thread
* [PATCH 1/6] object-file: prefer array-of-bytes initializer for hash literals
2024-11-18 9:54 ` [PATCH 0/6] -Wunterminated-string-initialization warning + cleanups Jeff King
@ 2024-11-18 9:54 ` Jeff King
2024-11-18 9:55 ` [PATCH 2/6] object-file: drop confusing oid initializer of empty_tree struct Jeff King
` (5 subsequent siblings)
6 siblings, 0 replies; 25+ messages in thread
From: Jeff King @ 2024-11-18 9:54 UTC (permalink / raw)
To: Sam James
Cc: René Scharfe, Patrick Steinhardt, Chris Torek,
brian m. carlson, git
We hard-code a few well-known hash values for empty trees and blobs in
both sha1 and sha256 formats. We do so with string literals like this:
#define EMPTY_TREE_SHA256_BIN_LITERAL \
"\x6e\xf1\x9b\x41\x22\x5c\x53\x69\xf1\xc1" \
"\x04\xd4\x5d\x8d\x85\xef\xa9\xb0\x57\xb5" \
"\x3b\x14\xb4\xb9\xb9\x39\xdd\x74\xde\xcc" \
"\x53\x21"
and then use it to initialize the hash field of an object_id struct.
That hash field is exactly 32 bytes long (the size we need for sha256).
But the string literal above is actually 33 bytes long due to the NUL
terminator. This is legal in C, and the NUL is ignored.
Side note on legality: in general excess initializer elements are
forbidden, and gcc will warn on both of these:
char foo[3] = { 'h', 'u', 'g', 'e' };
char bar[3] = "VeryLongString";
I couldn't find specific language in the standard allowing
initialization from a string literal where _just_ the NUL is ignored,
but C99 section 6.7.8 (Initialization), paragraph 32 shows this exact
case as "example 8".
However, the upcoming gcc 15 will start warning for this case (when
compiled with -Wextra via DEVELOPER=1):
CC object-file.o
object-file.c:52:9: warning: initializer-string for array of ‘unsigned char’ is too long [-Wunterminated-string-initialization]
52 | "\x6e\xf1\x9b\x41\x22\x5c\x53\x69\xf1\xc1" \
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
object-file.c:79:17: note: in expansion of macro ‘EMPTY_TREE_SHA256_BIN_LITERAL’
which is understandable. Even though this is not a bug for us, since we
do not care about the NUL terminator (and are just using the literal as
a convenient format), it would be easy to accidentally create an array
that was mistakenly unterminated.
We can avoid this warning by switching the initializer to an actual
array of unsigned values. That arguably demonstrates our intent more
clearly anyway.
Reported-by: Sam James <sam@gentoo•org>
Signed-off-by: Jeff King <peff@peff•net>
---
object-file.c | 38 +++++++++++++++++++++-----------------
1 file changed, 21 insertions(+), 17 deletions(-)
diff --git a/object-file.c b/object-file.c
index b1a3463852..8101585616 100644
--- a/object-file.c
+++ b/object-file.c
@@ -45,23 +45,27 @@
#define MAX_HEADER_LEN 32
-#define EMPTY_TREE_SHA1_BIN_LITERAL \
- "\x4b\x82\x5d\xc6\x42\xcb\x6e\xb9\xa0\x60" \
- "\xe5\x4b\xf8\xd6\x92\x88\xfb\xee\x49\x04"
-#define EMPTY_TREE_SHA256_BIN_LITERAL \
- "\x6e\xf1\x9b\x41\x22\x5c\x53\x69\xf1\xc1" \
- "\x04\xd4\x5d\x8d\x85\xef\xa9\xb0\x57\xb5" \
- "\x3b\x14\xb4\xb9\xb9\x39\xdd\x74\xde\xcc" \
- "\x53\x21"
-
-#define EMPTY_BLOB_SHA1_BIN_LITERAL \
- "\xe6\x9d\xe2\x9b\xb2\xd1\xd6\x43\x4b\x8b" \
- "\x29\xae\x77\x5a\xd8\xc2\xe4\x8c\x53\x91"
-#define EMPTY_BLOB_SHA256_BIN_LITERAL \
- "\x47\x3a\x0f\x4c\x3b\xe8\xa9\x36\x81\xa2" \
- "\x67\xe3\xb1\xe9\xa7\xdc\xda\x11\x85\x43" \
- "\x6f\xe1\x41\xf7\x74\x91\x20\xa3\x03\x72" \
- "\x18\x13"
+#define EMPTY_TREE_SHA1_BIN_LITERAL { \
+ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, \
+ 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 \
+}
+#define EMPTY_TREE_SHA256_BIN_LITERAL { \
+ 0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1, \
+ 0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5, \
+ 0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc, \
+ 0x53, 0x21 \
+}
+
+#define EMPTY_BLOB_SHA1_BIN_LITERAL { \
+ 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b, \
+ 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 \
+}
+#define EMPTY_BLOB_SHA256_BIN_LITERAL { \
+ 0x47, 0x3a, 0x0f, 0x4c, 0x3b, 0xe8, 0xa9, 0x36, 0x81, 0xa2, \
+ 0x67, 0xe3, 0xb1, 0xe9, 0xa7, 0xdc, 0xda, 0x11, 0x85, 0x43, \
+ 0x6f, 0xe1, 0x41, 0xf7, 0x74, 0x91, 0x20, 0xa3, 0x03, 0x72, \
+ 0x18, 0x13 \
+}
static const struct object_id empty_tree_oid = {
.hash = EMPTY_TREE_SHA1_BIN_LITERAL,
--
2.47.0.547.g778689293a
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 2/6] object-file: drop confusing oid initializer of empty_tree struct
2024-11-18 9:54 ` [PATCH 0/6] -Wunterminated-string-initialization warning + cleanups Jeff King
2024-11-18 9:54 ` [PATCH 1/6] object-file: prefer array-of-bytes initializer for hash literals Jeff King
@ 2024-11-18 9:55 ` Jeff King
2024-11-18 9:55 ` [PATCH 3/6] object-file: move empty_tree struct into find_cached_object() Jeff King
` (4 subsequent siblings)
6 siblings, 0 replies; 25+ messages in thread
From: Jeff King @ 2024-11-18 9:55 UTC (permalink / raw)
To: Sam James
Cc: René Scharfe, Patrick Steinhardt, Chris Torek,
brian m. carlson, git
We treat the empty tree specially, providing an in-memory "cached" copy,
which allows you to diff against it even if the object doesn't exist in
the repository. This is implemented as part of the larger cached_object
subsystem, but we use a stand-alone empty_tree struct.
We initialize the oid of that struct using EMPTY_TREE_SHA1_BIN_LITERAL.
At first glance, that seems like a bug; how could this ever work for
sha256 repositories?
The answer is that we never look at the oid field! The oid field is used
to look up entries added by pretend_object_file() to the cached_objects
array. But for our stand-alone entry, we look for it independently using
the_hash_algo->empty_tree, which will point to the correct algo struct
for the repository.
This happened in 62ba93eaa9 (sha1_file: convert cached object code to
struct object_id, 2018-05-02), which even mentions that this field is
never used. Let's reduce confusion for anybody reading this code by
replacing the sha1 initializer with a comment. The resulting field will
be all-zeroes, so any violation of our assumption that the oid field is
not used will break equally for sha1 and sha256.
Signed-off-by: Jeff King <peff@peff•net>
---
object-file.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/object-file.c b/object-file.c
index 8101585616..19fc4afa43 100644
--- a/object-file.c
+++ b/object-file.c
@@ -326,9 +326,7 @@ static struct cached_object {
static int cached_object_nr, cached_object_alloc;
static struct cached_object empty_tree = {
- .oid = {
- .hash = EMPTY_TREE_SHA1_BIN_LITERAL,
- },
+ /* no oid needed; we'll look it up manually based on the_hash_algo */
.type = OBJ_TREE,
.buf = "",
};
--
2.47.0.547.g778689293a
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 3/6] object-file: move empty_tree struct into find_cached_object()
2024-11-18 9:54 ` [PATCH 0/6] -Wunterminated-string-initialization warning + cleanups Jeff King
2024-11-18 9:54 ` [PATCH 1/6] object-file: prefer array-of-bytes initializer for hash literals Jeff King
2024-11-18 9:55 ` [PATCH 2/6] object-file: drop confusing oid initializer of empty_tree struct Jeff King
@ 2024-11-18 9:55 ` Jeff King
2024-11-18 9:55 ` [PATCH 4/6] object-file: drop oid field from find_cached_object() return value Jeff King
` (3 subsequent siblings)
6 siblings, 0 replies; 25+ messages in thread
From: Jeff King @ 2024-11-18 9:55 UTC (permalink / raw)
To: Sam James
Cc: René Scharfe, Patrick Steinhardt, Chris Torek,
brian m. carlson, git
The fake empty_tree struct is a static global, but the only code that
looks at it is find_cached_object(). The struct itself is a little odd,
with an invalid "oid" field that is handled specially by that function.
Since it's really just an implementation detail, let's move it to a
static within the function. That future-proofs against other code trying
to use it and seeing the weird oid value.
Signed-off-by: Jeff King <peff@peff•net>
---
object-file.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/object-file.c b/object-file.c
index 19fc4afa43..4d4280543e 100644
--- a/object-file.c
+++ b/object-file.c
@@ -325,14 +325,13 @@ static struct cached_object {
} *cached_objects;
static int cached_object_nr, cached_object_alloc;
-static struct cached_object empty_tree = {
- /* no oid needed; we'll look it up manually based on the_hash_algo */
- .type = OBJ_TREE,
- .buf = "",
-};
-
static struct cached_object *find_cached_object(const struct object_id *oid)
{
+ static struct cached_object empty_tree = {
+ /* no oid needed; we'll look it up manually based on the_hash_algo */
+ .type = OBJ_TREE,
+ .buf = "",
+ };
int i;
struct cached_object *co = cached_objects;
--
2.47.0.547.g778689293a
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 4/6] object-file: drop oid field from find_cached_object() return value
2024-11-18 9:54 ` [PATCH 0/6] -Wunterminated-string-initialization warning + cleanups Jeff King
` (2 preceding siblings ...)
2024-11-18 9:55 ` [PATCH 3/6] object-file: move empty_tree struct into find_cached_object() Jeff King
@ 2024-11-18 9:55 ` Jeff King
2024-11-18 9:55 ` [PATCH 5/6] object-file: treat cached_object values as const Jeff King
` (2 subsequent siblings)
6 siblings, 0 replies; 25+ messages in thread
From: Jeff King @ 2024-11-18 9:55 UTC (permalink / raw)
To: Sam James
Cc: René Scharfe, Patrick Steinhardt, Chris Torek,
brian m. carlson, git
The pretend_object_file() function adds to an array mapping oids to
object contents, which are later retrieved with find_cached_object().
We naturally need to store the oid for each entry, since it's the lookup
key.
But find_cached_object() also returns a hard-coded empty_tree object.
There we don't care about its oid field and instead compare against
the_hash_algo->empty_tree. The oid field is left as all-zeroes.
This all works, but it means that the cached_object struct we return
from find_cached_object() may or may not have a valid oid field, depend
whether it is the hard-coded tree or came from pretend_object_file().
Nobody looks at the field, so there's no bug. But let's future-proof it
by returning only the object contents themselves, not the oid. We'll
continue to call this "struct cached_object", and the array entry
mapping the key to those contents will be a "cached_object_entry".
This would also let us swap out the array for a better data structure
(like a hashmap) if we chose, but there's not much point. The only code
that adds an entry is git-blame, which adds at most a single entry per
process.
Signed-off-by: Jeff King <peff@peff•net>
---
object-file.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)
diff --git a/object-file.c b/object-file.c
index 4d4280543e..67a6731066 100644
--- a/object-file.c
+++ b/object-file.c
@@ -317,27 +317,28 @@ int hash_algo_by_length(int len)
* to write them into the object store (e.g. a browse-only
* application).
*/
-static struct cached_object {
+static struct cached_object_entry {
struct object_id oid;
- enum object_type type;
- const void *buf;
- unsigned long size;
+ struct cached_object {
+ enum object_type type;
+ const void *buf;
+ unsigned long size;
+ } value;
} *cached_objects;
static int cached_object_nr, cached_object_alloc;
static struct cached_object *find_cached_object(const struct object_id *oid)
{
static struct cached_object empty_tree = {
- /* no oid needed; we'll look it up manually based on the_hash_algo */
.type = OBJ_TREE,
.buf = "",
};
int i;
- struct cached_object *co = cached_objects;
+ struct cached_object_entry *co = cached_objects;
for (i = 0; i < cached_object_nr; i++, co++) {
if (oideq(&co->oid, oid))
- return co;
+ return &co->value;
}
if (oideq(oid, the_hash_algo->empty_tree))
return &empty_tree;
@@ -1850,7 +1851,7 @@ int oid_object_info(struct repository *r,
int pretend_object_file(void *buf, unsigned long len, enum object_type type,
struct object_id *oid)
{
- struct cached_object *co;
+ struct cached_object_entry *co;
char *co_buf;
hash_object_file(the_hash_algo, buf, len, type, oid);
@@ -1859,11 +1860,11 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type,
return 0;
ALLOC_GROW(cached_objects, cached_object_nr + 1, cached_object_alloc);
co = &cached_objects[cached_object_nr++];
- co->size = len;
- co->type = type;
+ co->value.size = len;
+ co->value.type = type;
co_buf = xmalloc(len);
memcpy(co_buf, buf, len);
- co->buf = co_buf;
+ co->value.buf = co_buf;
oidcpy(&co->oid, oid);
return 0;
}
--
2.47.0.547.g778689293a
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 5/6] object-file: treat cached_object values as const
2024-11-18 9:54 ` [PATCH 0/6] -Wunterminated-string-initialization warning + cleanups Jeff King
` (3 preceding siblings ...)
2024-11-18 9:55 ` [PATCH 4/6] object-file: drop oid field from find_cached_object() return value Jeff King
@ 2024-11-18 9:55 ` Jeff King
2024-11-18 9:55 ` [PATCH 6/6] object-file: inline empty tree and blob literals Jeff King
2024-11-18 10:51 ` [PATCH 0/6] -Wunterminated-string-initialization warning + cleanups Patrick Steinhardt
6 siblings, 0 replies; 25+ messages in thread
From: Jeff King @ 2024-11-18 9:55 UTC (permalink / raw)
To: Sam James
Cc: René Scharfe, Patrick Steinhardt, Chris Torek,
brian m. carlson, git
The cached-object API maps oids to in-memory entries. Once inserted,
these entries should be immutable. Let's return them from the
find_cached_object() call with a const tag to make this clear.
Suggested-by: Patrick Steinhardt <ps@pks•im>
Signed-off-by: Jeff King <peff@peff•net>
---
object-file.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/object-file.c b/object-file.c
index 67a6731066..ec62e5fb3b 100644
--- a/object-file.c
+++ b/object-file.c
@@ -327,14 +327,14 @@ static struct cached_object_entry {
} *cached_objects;
static int cached_object_nr, cached_object_alloc;
-static struct cached_object *find_cached_object(const struct object_id *oid)
+static const struct cached_object *find_cached_object(const struct object_id *oid)
{
- static struct cached_object empty_tree = {
+ static const struct cached_object empty_tree = {
.type = OBJ_TREE,
.buf = "",
};
int i;
- struct cached_object_entry *co = cached_objects;
+ const struct cached_object_entry *co = cached_objects;
for (i = 0; i < cached_object_nr; i++, co++) {
if (oideq(&co->oid, oid))
@@ -1629,7 +1629,7 @@ static int do_oid_object_info_extended(struct repository *r,
struct object_info *oi, unsigned flags)
{
static struct object_info blank_oi = OBJECT_INFO_INIT;
- struct cached_object *co;
+ const struct cached_object *co;
struct pack_entry e;
int rtype;
const struct object_id *real = oid;
--
2.47.0.547.g778689293a
^ permalink raw reply related [flat|nested] 25+ messages in thread
* [PATCH 6/6] object-file: inline empty tree and blob literals
2024-11-18 9:54 ` [PATCH 0/6] -Wunterminated-string-initialization warning + cleanups Jeff King
` (4 preceding siblings ...)
2024-11-18 9:55 ` [PATCH 5/6] object-file: treat cached_object values as const Jeff King
@ 2024-11-18 9:55 ` Jeff King
2024-11-18 10:51 ` [PATCH 0/6] -Wunterminated-string-initialization warning + cleanups Patrick Steinhardt
6 siblings, 0 replies; 25+ messages in thread
From: Jeff King @ 2024-11-18 9:55 UTC (permalink / raw)
To: Sam James
Cc: René Scharfe, Patrick Steinhardt, Chris Torek,
brian m. carlson, git
We define macros with the bytes of the empty trees and blobs for sha1
and sha256. But since e1ccd7e2b1 (sha1_file: only expose empty object
constants through git_hash_algo, 2018-05-02), those are used only for
initializing the git_hash_algo entries. Any other code using the macros
directly would be suspicious, since a hash_algo pointer is the level of
indirection we use to make everything work with both sha1 and sha256.
So let's future proof against code doing the wrong thing by dropping the
macros entirely and just initializing the structs directly.
Signed-off-by: Jeff King <peff@peff•net>
---
object-file.c | 47 ++++++++++++++++++++---------------------------
1 file changed, 20 insertions(+), 27 deletions(-)
diff --git a/object-file.c b/object-file.c
index ec62e5fb3b..891eaa2b4b 100644
--- a/object-file.c
+++ b/object-file.c
@@ -44,47 +44,40 @@
/* The maximum size for an object header. */
#define MAX_HEADER_LEN 32
-
-#define EMPTY_TREE_SHA1_BIN_LITERAL { \
- 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60, \
- 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04 \
-}
-#define EMPTY_TREE_SHA256_BIN_LITERAL { \
- 0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1, \
- 0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5, \
- 0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc, \
- 0x53, 0x21 \
-}
-
-#define EMPTY_BLOB_SHA1_BIN_LITERAL { \
- 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b, \
- 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91 \
-}
-#define EMPTY_BLOB_SHA256_BIN_LITERAL { \
- 0x47, 0x3a, 0x0f, 0x4c, 0x3b, 0xe8, 0xa9, 0x36, 0x81, 0xa2, \
- 0x67, 0xe3, 0xb1, 0xe9, 0xa7, 0xdc, 0xda, 0x11, 0x85, 0x43, \
- 0x6f, 0xe1, 0x41, 0xf7, 0x74, 0x91, 0x20, 0xa3, 0x03, 0x72, \
- 0x18, 0x13 \
-}
-
static const struct object_id empty_tree_oid = {
- .hash = EMPTY_TREE_SHA1_BIN_LITERAL,
+ .hash = {
+ 0x4b, 0x82, 0x5d, 0xc6, 0x42, 0xcb, 0x6e, 0xb9, 0xa0, 0x60,
+ 0xe5, 0x4b, 0xf8, 0xd6, 0x92, 0x88, 0xfb, 0xee, 0x49, 0x04
+ },
.algo = GIT_HASH_SHA1,
};
static const struct object_id empty_blob_oid = {
- .hash = EMPTY_BLOB_SHA1_BIN_LITERAL,
+ .hash = {
+ 0xe6, 0x9d, 0xe2, 0x9b, 0xb2, 0xd1, 0xd6, 0x43, 0x4b, 0x8b,
+ 0x29, 0xae, 0x77, 0x5a, 0xd8, 0xc2, 0xe4, 0x8c, 0x53, 0x91
+ },
.algo = GIT_HASH_SHA1,
};
static const struct object_id null_oid_sha1 = {
.hash = {0},
.algo = GIT_HASH_SHA1,
};
static const struct object_id empty_tree_oid_sha256 = {
- .hash = EMPTY_TREE_SHA256_BIN_LITERAL,
+ .hash = {
+ 0x6e, 0xf1, 0x9b, 0x41, 0x22, 0x5c, 0x53, 0x69, 0xf1, 0xc1,
+ 0x04, 0xd4, 0x5d, 0x8d, 0x85, 0xef, 0xa9, 0xb0, 0x57, 0xb5,
+ 0x3b, 0x14, 0xb4, 0xb9, 0xb9, 0x39, 0xdd, 0x74, 0xde, 0xcc,
+ 0x53, 0x21
+ },
.algo = GIT_HASH_SHA256,
};
static const struct object_id empty_blob_oid_sha256 = {
- .hash = EMPTY_BLOB_SHA256_BIN_LITERAL,
+ .hash = {
+ 0x47, 0x3a, 0x0f, 0x4c, 0x3b, 0xe8, 0xa9, 0x36, 0x81, 0xa2,
+ 0x67, 0xe3, 0xb1, 0xe9, 0xa7, 0xdc, 0xda, 0x11, 0x85, 0x43,
+ 0x6f, 0xe1, 0x41, 0xf7, 0x74, 0x91, 0x20, 0xa3, 0x03, 0x72,
+ 0x18, 0x13
+ },
.algo = GIT_HASH_SHA256,
};
static const struct object_id null_oid_sha256 = {
--
2.47.0.547.g778689293a
^ permalink raw reply related [flat|nested] 25+ messages in thread
* Re: -Wunterminated-string-initialization warning with GCC 15 in object-file.c
2024-11-18 9:19 ` Jeff King
@ 2024-11-18 9:58 ` Sam James
0 siblings, 0 replies; 25+ messages in thread
From: Sam James @ 2024-11-18 9:58 UTC (permalink / raw)
To: Jeff King; +Cc: brian m. carlson, git
Jeff King <peff@peff•net> writes:
> On Sun, Nov 17, 2024 at 04:03:31PM +0000, brian m. carlson wrote:
>
>> On 2024-11-17 at 09:03:29, Jeff King wrote:
>> > Here are some patches. The first one should fix the warning (but I don't
>> > have gcc-15 handy to test!). Please let me know if it works for you (and
>> > thank you for reporting).
>>
>> Just so you know, since I believe you also use Debian unstable, you can
>> install the gcc-snapshot package (which is, admittedly, rather large)
>> and use `CC=/usr/lib/gcc-snapshot/bin/gcc`.
>
> Thanks, I was stupidly looking for a "gcc-15" package in experimental,
> not realizing it had not actually been released yet. I reproduced the
> problem with the snapshot (which is from 20241004) and verified that my
> series fixes it.
Sorry for not saying that explicitly -- I always try to balance some
long blurb of background and FYIs with not being verbose :(
I'll include it in future reports, sorry again!
>
> -Peff
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 0/6] -Wunterminated-string-initialization warning + cleanups
2024-11-18 9:54 ` [PATCH 0/6] -Wunterminated-string-initialization warning + cleanups Jeff King
` (5 preceding siblings ...)
2024-11-18 9:55 ` [PATCH 6/6] object-file: inline empty tree and blob literals Jeff King
@ 2024-11-18 10:51 ` Patrick Steinhardt
2024-11-18 12:49 ` Junio C Hamano
6 siblings, 1 reply; 25+ messages in thread
From: Patrick Steinhardt @ 2024-11-18 10:51 UTC (permalink / raw)
To: Jeff King
Cc: Sam James, René Scharfe, Chris Torek, brian m. carlson, git
On Mon, Nov 18, 2024 at 04:54:23AM -0500, Jeff King wrote:
> > Here are some patches. The first one should fix the warning (but I don't
> > have gcc-15 handy to test!). Please let me know if it works for you (and
> > thank you for reporting).
>
> And here's a minor re-roll from comments on the list. I was able to
> reproduce and test myself this time; the patch indeed fixes the problem.
Thanks, this version looks good to me!
Patrick
^ permalink raw reply [flat|nested] 25+ messages in thread
* Re: [PATCH 0/6] -Wunterminated-string-initialization warning + cleanups
2024-11-18 10:51 ` [PATCH 0/6] -Wunterminated-string-initialization warning + cleanups Patrick Steinhardt
@ 2024-11-18 12:49 ` Junio C Hamano
0 siblings, 0 replies; 25+ messages in thread
From: Junio C Hamano @ 2024-11-18 12:49 UTC (permalink / raw)
To: Patrick Steinhardt
Cc: Jeff King, Sam James, René Scharfe, Chris Torek,
brian m. carlson, git
Patrick Steinhardt <ps@pks•im> writes:
> On Mon, Nov 18, 2024 at 04:54:23AM -0500, Jeff King wrote:
>> > Here are some patches. The first one should fix the warning (but I don't
>> > have gcc-15 handy to test!). Please let me know if it works for you (and
>> > thank you for reporting).
>>
>> And here's a minor re-roll from comments on the list. I was able to
>> reproduce and test myself this time; the patch indeed fixes the problem.
>
> Thanks, this version looks good to me!
Thanks, both. Queued.
^ permalink raw reply [flat|nested] 25+ messages in thread
end of thread, other threads:[~2024-11-18 12:50 UTC | newest]
Thread overview: 25+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-11-17 2:50 -Wunterminated-string-initialization warning with GCC 15 in object-file.c Sam James
2024-11-17 9:03 ` Jeff King
2024-11-17 9:08 ` [PATCH 1/5] object-file: prefer array-of-bytes initializer for hash literals Jeff King
2024-11-17 9:52 ` René Scharfe
2024-11-18 9:06 ` Jeff King
2024-11-17 9:08 ` [PATCH 2/5] object-file: drop confusing oid initializer of empty_tree struct Jeff King
2024-11-17 9:08 ` [PATCH 3/5] object-file: move empty_tree struct into find_cached_object() Jeff King
2024-11-18 7:40 ` Patrick Steinhardt
2024-11-18 9:17 ` Jeff King
2024-11-17 9:10 ` [PATCH 4/5] object-file: drop oid field from find_cached_object() return value Jeff King
2024-11-17 9:14 ` [PATCH 5/5] object-file: inline empty tree and blob literals Jeff King
2024-11-18 7:40 ` Patrick Steinhardt
2024-11-17 16:03 ` -Wunterminated-string-initialization warning with GCC 15 in object-file.c brian m. carlson
2024-11-18 9:19 ` Jeff King
2024-11-18 9:58 ` Sam James
2024-11-18 7:40 ` Patrick Steinhardt
2024-11-18 9:54 ` [PATCH 0/6] -Wunterminated-string-initialization warning + cleanups Jeff King
2024-11-18 9:54 ` [PATCH 1/6] object-file: prefer array-of-bytes initializer for hash literals Jeff King
2024-11-18 9:55 ` [PATCH 2/6] object-file: drop confusing oid initializer of empty_tree struct Jeff King
2024-11-18 9:55 ` [PATCH 3/6] object-file: move empty_tree struct into find_cached_object() Jeff King
2024-11-18 9:55 ` [PATCH 4/6] object-file: drop oid field from find_cached_object() return value Jeff King
2024-11-18 9:55 ` [PATCH 5/6] object-file: treat cached_object values as const Jeff King
2024-11-18 9:55 ` [PATCH 6/6] object-file: inline empty tree and blob literals Jeff King
2024-11-18 10:51 ` [PATCH 0/6] -Wunterminated-string-initialization warning + cleanups Patrick Steinhardt
2024-11-18 12:49 ` Junio C Hamano
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox