summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2020-09-30 15:26:24 (GMT)
committerJunio C Hamano <gitster@pobox.com>2020-09-30 20:26:54 (GMT)
commit0ad621f61e4b2adc3a7bad088c25ebf2c8b9f43d (patch)
treea50c0af62adeba71d64d70f93369ca793075aecc
parentf2f1250c47fd967b7678cad329438e8deac62038 (diff)
downloadgit-0ad621f61e4b2adc3a7bad088c25ebf2c8b9f43d.zip
git-0ad621f61e4b2adc3a7bad088c25ebf2c8b9f43d.tar.gz
git-0ad621f61e4b2adc3a7bad088c25ebf2c8b9f43d.tar.bz2
hashmap_for_each_entry(): workaround MSVC's runtime check failure #3
The OFFSETOF_VAR(var, member) macro is implemented in terms of offsetof(typeof(*var), member) with compilers that know typeof(), but its fallback implemenation compares &(var->member) and (var) and count the distance in bytes, i.e. ((uintptr_t)&(var)->member - (uintptr_t)(var)) MSVC's runtime check, when fed an uninitialized 'var', flags this as a use of an uninitialized variable (and that is legit---uninitialized contents of 'var' is subtracted) in a debug build. After auditing all 6 uses of OFFSETOF_VAR(), 1 of them does feed a potentially uninitialized 'var' to the macro in the beginning of the for() loop: #define hashmap_for_each_entry(map, iter, var, member) \ for (var = hashmap_iter_first_entry_offset(map, iter, \ OFFSETOF_VAR(var, member)); \ var; \ var = hashmap_iter_next_entry_offset(iter, \ OFFSETOF_VAR(var, member))) We can work around this by making sure that var has _some_ value when OFFSETOF_VAR() is called. Strictly speaking, it invites undefined behaviour to use NULL here if we end up with pointer comparison, but MSVC runtime seems to be happy with it, and most other systems have typeof() and don't even need pointer comparison fallback code. Signed-off-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--hashmap.h3
1 files changed, 2 insertions, 1 deletions
diff --git a/hashmap.h b/hashmap.h
index ef220de..b011b39 100644
--- a/hashmap.h
+++ b/hashmap.h
@@ -449,7 +449,8 @@ static inline struct hashmap_entry *hashmap_iter_first(struct hashmap *map,
* containing a @member which is a "struct hashmap_entry"
*/
#define hashmap_for_each_entry(map, iter, var, member) \
- for (var = hashmap_iter_first_entry_offset(map, iter, \
+ for (var = NULL, /* for systems without typeof */ \
+ var = hashmap_iter_first_entry_offset(map, iter, \
OFFSETOF_VAR(var, member)); \
var; \
var = hashmap_iter_next_entry_offset(iter, \