Commit 9eb17d460cd681bbc14d56ed8fdf440bc69b5456

lhchavez 2021-02-16T19:38:34

Introduce GIT_WARN_UNUSED_RESULT This change adds the GIT_WARN_UNUSED_RESULT annotation, which makes the compiler warn when a return result is not used. This avoids bugs.

diff --git a/include/git2/common.h b/include/git2/common.h
index 4402dfd..5f64a37 100644
--- a/include/git2/common.h
+++ b/include/git2/common.h
@@ -71,6 +71,13 @@ typedef size_t size_t;
 # define GIT_FORMAT_PRINTF(a,b) /* empty */
 #endif
 
+/** Declare that a function's return value must be used. */
+#if defined(__GNUC__)
+# define GIT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
+#else
+# define GIT_WARN_UNUSED_RESULT
+#endif
+
 #if (defined(_WIN32)) && !defined(__CYGWIN__)
 #define GIT_WIN32 1
 #endif
diff --git a/src/sortedcache.h b/src/sortedcache.h
index ca8b106..eb74be9 100644
--- a/src/sortedcache.h
+++ b/src/sortedcache.h
@@ -58,7 +58,7 @@ typedef struct {
  *        may be NULL.  The cache makes it easy to load this and check
  *        if it has been modified since the last load and/or write.
  */
-int git_sortedcache_new(
+GIT_WARN_UNUSED_RESULT int git_sortedcache_new(
 	git_sortedcache **out,
 	size_t item_path_offset, /* use offsetof(struct, path-field) macro */
 	git_sortedcache_free_item_fn free_item,
@@ -71,7 +71,7 @@ int git_sortedcache_new(
  * - `copy_item` can be NULL to just use memcpy
  * - if `lock`, grabs read lock on `src` during copy and releases after
  */
-int git_sortedcache_copy(
+GIT_WARN_UNUSED_RESULT int git_sortedcache_copy(
 	git_sortedcache **out,
 	git_sortedcache *src,
 	bool lock,
@@ -88,7 +88,7 @@ void git_sortedcache_free(git_sortedcache *sc);
 void git_sortedcache_incref(git_sortedcache *sc);
 
 /* Get the pathname associated with this cache at creation time */
-const char *git_sortedcache_path(git_sortedcache *sc);
+GIT_WARN_UNUSED_RESULT const char *git_sortedcache_path(git_sortedcache *sc);
 
 /*
  * CACHE WRITE FUNCTIONS
@@ -100,7 +100,7 @@ const char *git_sortedcache_path(git_sortedcache *sc);
  */
 
 /* Lock sortedcache for write */
-int git_sortedcache_wlock(git_sortedcache *sc);
+GIT_WARN_UNUSED_RESULT int git_sortedcache_wlock(git_sortedcache *sc);
 
 /* Unlock sorted cache when done with write */
 void git_sortedcache_wunlock(git_sortedcache *sc);
@@ -120,7 +120,8 @@ void git_sortedcache_wunlock(git_sortedcache *sc);
  *
  * @return 0 if up-to-date, 1 if out-of-date, <0 on error
  */
-int git_sortedcache_lockandload(git_sortedcache *sc, git_buf *buf);
+GIT_WARN_UNUSED_RESULT int git_sortedcache_lockandload(
+	git_sortedcache *sc, git_buf *buf);
 
 /* Refresh file timestamp after write completes
  * You should already be holding the write lock when you call this.
@@ -137,13 +138,13 @@ int git_sortedcache_clear(git_sortedcache *sc, bool wlock);
 /* Find and/or insert item, returning pointer to item data.
  * You should already be holding the write lock when you call this.
  */
-int git_sortedcache_upsert(
+GIT_WARN_UNUSED_RESULT int git_sortedcache_upsert(
 	void **out, git_sortedcache *sc, const char *key);
 
 /* Removes entry at pos from cache
  * You should already be holding the write lock when you call this.
  */
-int git_sortedcache_remove(git_sortedcache *sc, size_t pos);
+GIT_WARN_UNUSED_RESULT int git_sortedcache_remove(git_sortedcache *sc, size_t pos);
 
 /*
  * CACHE READ FUNCTIONS
@@ -155,26 +156,29 @@ int git_sortedcache_remove(git_sortedcache *sc, size_t pos);
  */
 
 /* Lock sortedcache for read */
-int git_sortedcache_rlock(git_sortedcache *sc);
+GIT_WARN_UNUSED_RESULT int git_sortedcache_rlock(git_sortedcache *sc);
 
 /* Unlock sorted cache when done with read */
 void git_sortedcache_runlock(git_sortedcache *sc);
 
 /* Lookup item by key - returns NULL if not found */
-void *git_sortedcache_lookup(const git_sortedcache *sc, const char *key);
+GIT_WARN_UNUSED_RESULT void *git_sortedcache_lookup(
+	const git_sortedcache *sc, const char *key);
 
 /* Get how many items are in the cache
  *
  * You can call this function without holding a lock, but be aware
  * that it may change before you use it.
  */
-size_t git_sortedcache_entrycount(const git_sortedcache *sc);
+GIT_WARN_UNUSED_RESULT size_t git_sortedcache_entrycount(
+	const git_sortedcache *sc);
 
 /* Lookup item by index - returns NULL if out of range */
-void *git_sortedcache_entry(git_sortedcache *sc, size_t pos);
+GIT_WARN_UNUSED_RESULT void *git_sortedcache_entry(
+	git_sortedcache *sc, size_t pos);
 
 /* Lookup index of item by key - returns GIT_ENOTFOUND if not found */
-int git_sortedcache_lookup_index(
+GIT_WARN_UNUSED_RESULT int git_sortedcache_lookup_index(
 	size_t *out, git_sortedcache *sc, const char *key);
 
 #endif
diff --git a/src/vector.h b/src/vector.h
index cc4c314..3dcec3d 100644
--- a/src/vector.h
+++ b/src/vector.h
@@ -26,11 +26,13 @@ typedef struct git_vector {
 
 #define GIT_VECTOR_INIT {0}
 
-int git_vector_init(git_vector *v, size_t initial_size, git_vector_cmp cmp);
+GIT_WARN_UNUSED_RESULT int git_vector_init(
+	git_vector *v, size_t initial_size, git_vector_cmp cmp);
 void git_vector_free(git_vector *v);
 void git_vector_free_deep(git_vector *v); /* free each entry and self */
 void git_vector_clear(git_vector *v);
-int git_vector_dup(git_vector *v, const git_vector *src, git_vector_cmp cmp);
+GIT_WARN_UNUSED_RESULT int git_vector_dup(
+	git_vector *v, const git_vector *src, git_vector_cmp cmp);
 void git_vector_swap(git_vector *a, git_vector *b);
 int git_vector_size_hint(git_vector *v, size_t size_hint);
 
diff --git a/tests/core/vector.c b/tests/core/vector.c
index a7e1a03..08cd2c1 100644
--- a/tests/core/vector.c
+++ b/tests/core/vector.c
@@ -8,7 +8,7 @@ void test_core_vector__0(void)
 {
 	git_vector x;
 	int i;
-	git_vector_init(&x, 1, NULL);
+	cl_git_pass(git_vector_init(&x, 1, NULL));
 	for (i = 0; i < 10; ++i) {
 		git_vector_insert(&x, (void*) 0xabc);
 	}
@@ -21,7 +21,7 @@ void test_core_vector__1(void)
 {
 	git_vector x;
 	/* make initial capacity exact for our insertions. */
-	git_vector_init(&x, 3, NULL);
+	cl_git_pass(git_vector_init(&x, 3, NULL));
 	git_vector_insert(&x, (void*) 0xabc);
 	git_vector_insert(&x, (void*) 0xdef);
 	git_vector_insert(&x, (void*) 0x123);
@@ -76,7 +76,7 @@ void test_core_vector__3(void)
 {
 	git_vector x;
 	intptr_t i;
-	git_vector_init(&x, 1, &compare_them);
+	cl_git_pass(git_vector_init(&x, 1, &compare_them));
 
 	for (i = 0; i < 10; i += 2) {
 		git_vector_insert_sorted(&x, (void*)(i + 1), NULL);
@@ -99,7 +99,7 @@ void test_core_vector__4(void)
 {
 	git_vector x;
 	intptr_t i;
-	git_vector_init(&x, 1, &compare_them);
+	cl_git_pass(git_vector_init(&x, 1, &compare_them));
 
 	for (i = 0; i < 10; i += 2) {
 		git_vector_insert_sorted(&x, (void*)(i + 1), NULL);
@@ -163,7 +163,7 @@ void test_core_vector__5(void)
 	git_vector x;
 	int i;
 
-	git_vector_init(&x, 1, &compare_structs);
+	cl_git_pass(git_vector_init(&x, 1, &compare_structs));
 
 	for (i = 0; i < 10; i += 2)
 		git_vector_insert_sorted(&x, alloc_struct(i), &merge_structs);
@@ -205,7 +205,7 @@ void test_core_vector__remove_matching(void)
 	size_t i;
 	void *compare;
 
-	git_vector_init(&x, 1, NULL);
+	cl_git_pass(git_vector_init(&x, 1, NULL));
 	git_vector_insert(&x, (void*) 0x001);
 
 	cl_assert(x.length == 1);
diff --git a/tests/fetchhead/nonetwork.c b/tests/fetchhead/nonetwork.c
index 02e7ecf..6881af4 100644
--- a/tests/fetchhead/nonetwork.c
+++ b/tests/fetchhead/nonetwork.c
@@ -82,7 +82,7 @@ void test_fetchhead_nonetwork__write(void)
 	int equals = 0;
 	size_t i;
 
-	git_vector_init(&fetchhead_vector, 6, NULL);
+	cl_git_pass(git_vector_init(&fetchhead_vector, 6, NULL));
 
 	cl_set_cleanup(&cleanup_repository, "./test1");
 	cl_git_pass(git_repository_init(&g_repo, "./test1", 0));