From 4a9dd94b07ac6b8b7e1b7a5d21423afe1fdce7d3 Mon Sep 17 00:00:00 2001 From: Philipp Schafft Date: Mon, 1 Jul 2019 12:22:15 +0000 Subject: [PATCH] Fix: Corrected bugs related to incorrect check for transparent unions --- include/igloo/list.h | 3 ++- include/igloo/ro.h | 5 +++-- include/igloo/types.h | 4 +++- src/libigloo.c | 2 +- src/reportxml.c | 2 +- src/ro.c | 7 ++++--- src/tests/ctest_refobject.c | 8 ++++---- 7 files changed, 18 insertions(+), 13 deletions(-) diff --git a/include/igloo/list.h b/include/igloo/list.h index 7a1e2ab..053d166 100644 --- a/include/igloo/list.h +++ b/include/igloo/list.h @@ -97,8 +97,9 @@ int igloo_list_iterator_rewind(igloo_list_iterator_t *iterat do { \ igloo_list_iterator_storage_t __igloo_list_iterator_storage; \ igloo_list_iterator_t *__igloo_list_iterator = igloo_list_iterator_start((list), &__igloo_list_iterator_storage, sizeof(__igloo_list_iterator_storage)); \ + igloo_ro_t __igloo_ret; \ type * var; \ - for (; !igloo_RO_IS_NULL((var) = igloo_RO_TO_TYPE(igloo_list_iterator_next(__igloo_list_iterator),type));) { \ + for (; !igloo_RO_IS_NULL(__igloo_ret = igloo_list_iterator_next(__igloo_list_iterator)) && ((var) = igloo_RO_TO_TYPE(__igloo_ret,type));) { \ code; \ igloo_ro_unref((var)); \ } \ diff --git a/include/igloo/ro.h b/include/igloo/ro.h index d96ac5f..2b1cf9a 100644 --- a/include/igloo/ro.h +++ b/include/igloo/ro.h @@ -26,6 +26,7 @@ extern "C" { #include +#include #include "types.h" #include "thread.h" @@ -88,11 +89,11 @@ struct igloo_ro_base_tag { int igloo_ro_new__return_zero(igloo_ro_t self, const igloo_ro_type_t *type, va_list ap); /* ---[ END PRIVATE ]--- */ -#ifdef igloo_HAVE_TYPE_ATTRIBUTE_TRANSPARENT_UNION +#ifdef IGLOO_CTC_HAVE_TYPE_ATTRIBUTE_TRANSPARENT_UNION #define igloo_RO__GETBASE(x) (((igloo_ro_t)(x)).subtype__igloo_ro_base_t) #define igloo_RO_NULL ((igloo_ro_t)(igloo_ro_base_t*)NULL) #define igloo_RO_IS_NULL(x) (igloo_RO__GETBASE((x)) == NULL) -#define igloo_RO_TO_TYPE(x,type) (igloo_RO_IS_VALID((x),type) ? NULL : ((igloo_ro_t)(x)).subtype__ ## type) +#define igloo_RO_TO_TYPE(x,type) (igloo_RO_IS_VALID((x),type) ? ((igloo_ro_t)(x)).subtype__ ## type : NULL) #else #define igloo_RO__GETBASE(x) ((igloo_ro_base_t*)(x)) #define igloo_RO_NULL NULL diff --git a/include/igloo/types.h b/include/igloo/types.h index 2df5e6b..9c35b33 100644 --- a/include/igloo/types.h +++ b/include/igloo/types.h @@ -29,6 +29,8 @@ extern "C" { /* For size_t and ssize_t */ #include +#include + /* Included in case is not yet included */ #include "typedef.h" @@ -49,7 +51,7 @@ typedef struct igloo_reportxml_database_tag igloo_reportxml_database_t; typedef struct igloo_ro_base_tag igloo_ro_base_t; igloo_RO_FORWARD_TYPE(igloo_ro_base_t); -#ifdef igloo_HAVE_TYPE_ATTRIBUTE_TRANSPARENT_UNION +#ifdef IGLOO_CTC_HAVE_TYPE_ATTRIBUTE_TRANSPARENT_UNION typedef union __attribute__ ((__transparent_union__)) { /* Those are libigloo's own types */ igloo_RO_TYPE(igloo_ro_base_t) diff --git a/src/libigloo.c b/src/libigloo.c index 55ba916..863a34d 100644 --- a/src/libigloo.c +++ b/src/libigloo.c @@ -72,5 +72,5 @@ igloo_ro_t igloo_initialize(void) igloo_initialize__refc++; - return ret; + return (igloo_ro_t)ret; } diff --git a/src/reportxml.c b/src/reportxml.c index 978f290..f77be62 100644 --- a/src/reportxml.c +++ b/src/reportxml.c @@ -1137,7 +1137,7 @@ static igloo_reportxml_node_t * __reportxml_database_build_node_ext(igloo_r } igloo_thread_mutex_lock(&(db->lock)); - if (igloo_avl_get_by_key(db->definitions, igloo_RO_TO_TYPE(search, void *), (void**)&found) != 0) { + if (igloo_avl_get_by_key(db->definitions, (void*)search, (void**)&found) != 0) { igloo_thread_mutex_unlock(&(db->lock)); igloo_ro_unref(search); return NULL; diff --git a/src/ro.c b/src/ro.c index 8dab62c..1e985d0 100644 --- a/src/ro.c +++ b/src/ro.c @@ -147,9 +147,8 @@ int igloo_ro_unref(igloo_ro_t self) return -1; } - base->refc--; - - if (base->refc) { + if (base->refc > 1) { + base->refc--; igloo_thread_mutex_unlock(&(base->lock)); return 0; } @@ -157,6 +156,8 @@ int igloo_ro_unref(igloo_ro_t self) if (base->type->type_freecb) base->type->type_freecb(self); + base->refc--; + igloo_ro_unref(base->associated); if (base->name) diff --git a/src/tests/ctest_refobject.c b/src/tests/ctest_refobject.c index 4c061f5..1c19de6 100644 --- a/src/tests/ctest_refobject.c +++ b/src/tests/ctest_refobject.c @@ -152,21 +152,21 @@ static void test_sizes(void) { igloo_ro_t a; - a = igloo_ro_new(ctest_test_type_a_t); + a = (igloo_ro_t)igloo_ro_new(ctest_test_type_a_t); ctest_test("refobject created with size=sizeof(igloo_ro_base_t) + 1024", !igloo_RO_IS_NULL(a)); ctest_test("un-referenced", igloo_ro_unref(a) == 0); - a = igloo_ro_new(ctest_test_type_b_t); + a = (igloo_ro_t)igloo_ro_new(ctest_test_type_b_t); ctest_test("refobject created with size=sizeof(igloo_ro_base_t) + 131072", !igloo_RO_IS_NULL(a)); ctest_test("un-referenced", igloo_ro_unref(a) == 0); - a = igloo_ro_new(ctest_test_type_c_t); + a = (igloo_ro_t)igloo_ro_new(ctest_test_type_c_t); ctest_test("refobject created with size=sizeof(igloo_ro_base_t) - 1", igloo_RO_IS_NULL(a)); if (!igloo_RO_IS_NULL(a)) { ctest_test("un-referenced", igloo_ro_unref(a) == 0); } - a = igloo_ro_new(ctest_test_type_d_t); + a = (igloo_ro_t)igloo_ro_new(ctest_test_type_d_t); ctest_test("refobject created with size=0", igloo_RO_IS_NULL(a)); if (!igloo_RO_IS_NULL(a)) { ctest_test("un-referenced", igloo_ro_unref(a) == 0);