dte test coverage


Directory: ./
File: src/util/xmalloc.c
Date: 2025-05-08 15:05:54
Exec Total Coverage
Lines: 39 39 100.0%
Functions: 9 9 100.0%
Branches: 4 8 50.0%

Line Branch Exec Source
1 #include <errno.h>
2 #include <limits.h>
3 #include <stdarg.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include "xmalloc.h"
7 #include "debug.h"
8 #include "xsnprintf.h"
9
10 75852 static void *check_alloc(void *alloc)
11 {
12
1/2
✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→4) taken 75852 times.
75852 if (unlikely(alloc == NULL)) {
13 fatal_error(__func__, ENOMEM);
14 }
15 75852 return alloc;
16 }
17
18 14002 size_t xmul_(size_t a, size_t b)
19 {
20 14002 size_t result;
21
1/2
✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 14002 times.
14002 if (unlikely(size_multiply_overflows(a, b, &result))) {
22 fatal_error(__func__, EOVERFLOW);
23 }
24 14002 return result;
25 }
26
27 206084 size_t xadd(size_t a, size_t b)
28 {
29 206084 size_t result;
30
1/2
✗ Branch 0 (3→4) not taken.
✓ Branch 1 (3→5) taken 206084 times.
206084 if (unlikely(size_add_overflows(a, b, &result))) {
31 fatal_error(__func__, EOVERFLOW);
32 }
33 206084 return result;
34 }
35
36 // Like malloc(3), but calling fatal_error() on OOM and forbidding
37 // zero-sized allocations (thus never returning NULL)
38 44182 void *xmalloc(size_t size)
39 {
40 44182 BUG_ON(size == 0);
41 44182 return check_alloc(malloc(size));
42 }
43
44 3747 void *xcalloc(size_t nmemb, size_t size)
45 {
46 3747 if (__STDC_VERSION__ < 202311L) {
47 // ISO C23 (ยง7.24.3.2) requires calloc() to check for integer
48 // overflow in `nmemb * size`, but older C standards don't
49 xmul(nmemb, size);
50 }
51
52 3747 BUG_ON(nmemb == 0 || size == 0);
53 3747 return check_alloc(calloc(nmemb, size));
54 }
55
56 12160 void *xrealloc(void *ptr, size_t size)
57 {
58 12160 BUG_ON(size == 0);
59 12160 return check_alloc(realloc(ptr, size));
60 }
61
62 15763 char *xstrdup(const char *str)
63 {
64 15763 return check_alloc(strdup(str));
65 }
66
67 VPRINTF(1)
68 2 static char *xvasprintf(const char *format, va_list ap)
69 {
70 2 va_list ap2;
71 2 va_copy(ap2, ap);
72 2 int n = vsnprintf(NULL, 0, format, ap2);
73 2 va_end(ap2);
74
75
1/2
✗ Branch 0 (2→3) not taken.
✓ Branch 1 (2→6) taken 2 times.
2 if (unlikely(n < 0 || n == INT_MAX)) {
76 fatal_error(__func__, n < 0 ? errno : EOVERFLOW);
77 }
78
79 2 char *str = xmalloc(n + 1);
80 2 size_t m = xvsnprintf(str, n + 1, format, ap);
81 2 BUG_ON(m != n);
82 2 return str;
83 }
84
85 2 char *xasprintf(const char *format, ...)
86 {
87 2 va_list ap;
88 2 va_start(ap, format);
89 2 char *str = xvasprintf(format, ap);
90 2 va_end(ap);
91 2 return str;
92 }
93