0
0
mirror of https://gitlab.nic.cz/labs/bird.git synced 2024-12-22 17:51:53 +00:00

C Compiler Attribute Cleanup Test

There is a long-known CC attribute cleanup which allows to call a custom
cleanup function when an auto-storage variable ceases to exist. We're
gonna use it for end-of-loop and leave-locked-block macros.

This commit adds a static unit test for this compiler feature to be sure
that it really does what we want. We're looking forward to the next ISO
C norm where this may finally get a nice syntax and standardization.
This commit is contained in:
Maria Matejka 2023-10-26 23:09:20 +02:00
parent 87e2ba8c84
commit 980ef11016
3 changed files with 84 additions and 1 deletions

View File

@ -2,6 +2,6 @@ src := bitmap.c bitops.c blake2s.c blake2b.c checksum.c event.c flowspec.c idm.c
obj := $(src-o-files) obj := $(src-o-files)
$(all-daemon) $(all-daemon)
tests_src := bitmap_test.c heap_test.c buffer_test.c event_test.c flowspec_test.c bitops_test.c patmatch_test.c fletcher16_test.c slist_test.c checksum_test.c lists_test.c mac_test.c ip_test.c hash_test.c printf_test.c slab_test.c tests_src := attribute_cleanup_test.c bitmap_test.c heap_test.c buffer_test.c event_test.c flowspec_test.c bitops_test.c patmatch_test.c fletcher16_test.c slist_test.c checksum_test.c lists_test.c mac_test.c ip_test.c hash_test.c printf_test.c slab_test.c
tests_targets := $(tests_targets) $(tests-target-files) tests_targets := $(tests_targets) $(tests-target-files)
tests_objs := $(tests_objs) $(src-o-files) tests_objs := $(tests_objs) $(src-o-files)

View File

@ -0,0 +1,82 @@
/*
* BIRD Library -- Auto storage attribute cleanup test
*
* (c) 2023 Maria Matejka <mq@jmq.cz>
* (c) 2023 CZ.NIC z.s.p.o.
*
* Can be freely distributed and used under the terms of the GNU GPL.
*/
#include "test/birdtest.h"
static int order_pos;
#define CHECK(n) bt_assert(order_pos++ == (n))
static void
tacd_cleanup(int *val)
{
CHECK(*val);
}
static void
tacd_aux(int pos)
{
CHECK(pos + 0);
UNUSED CLEANUP(tacd_cleanup) int upmost = pos + 18;
if (order_pos > 0)
{
CHECK(pos + 1);
UNUSED CLEANUP(tacd_cleanup) int inner_if = pos + 3;
CHECK(pos + 2);
}
for (int i=0; i<3; i++)
{
CHECK(pos + 4 + 3*i);
UNUSED CLEANUP(tacd_cleanup) int inner_for = pos + 6 + 3*i;
CHECK(pos + 5 + 3*i);
}
for (
CLEANUP(tacd_cleanup) int i = pos + 15;
i < pos + 16; i++)
{
CHECK(pos + 13);
UNUSED CLEANUP(tacd_cleanup) int inner_for = pos + 15;
CHECK(pos + 14);
}
CHECK(pos + 17);
}
#define CHECKCNT 19
static int
t_attribute_cleanup(void)
{
order_pos = 0;
CHECK(0);
for (int i=0; i<3; i++)
{
CHECK(i*(CHECKCNT+3) + 1);
UNUSED CLEANUP(tacd_cleanup) int inner_for = (i+1) * (CHECKCNT+3);
tacd_aux(i*(CHECKCNT+3) + 2);
CHECK((i+1) * (CHECKCNT+3) - 1);
}
CHECK(3 * (CHECKCNT+3) + 1);
return 1;
}
int main(int argc, char **argv)
{
bt_init(argc, argv);
bt_test_suite(t_attribute_cleanup, "Basic usability of the cleanup attribute");
return bt_exit_value();
}

View File

@ -76,6 +76,7 @@ static inline int u64_cmp(u64 i1, u64 i2)
#define UNUSED __attribute__((unused)) #define UNUSED __attribute__((unused))
#define PACKED __attribute__((packed)) #define PACKED __attribute__((packed))
#define NONNULL(...) __attribute__((nonnull((__VA_ARGS__)))) #define NONNULL(...) __attribute__((nonnull((__VA_ARGS__))))
#define CLEANUP(fun) __attribute__((cleanup(fun)))
#define STATIC_ASSERT(EXP) _Static_assert(EXP, #EXP) #define STATIC_ASSERT(EXP) _Static_assert(EXP, #EXP)
#define STATIC_ASSERT_MSG(EXP,MSG) _Static_assert(EXP, MSG) #define STATIC_ASSERT_MSG(EXP,MSG) _Static_assert(EXP, MSG)