summaryrefslogtreecommitdiffstats
path: root/gl/xsize.h
diff options
context:
space:
mode:
Diffstat (limited to 'gl/xsize.h')
-rw-r--r--gl/xsize.h38
1 files changed, 30 insertions, 8 deletions
diff --git a/gl/xsize.h b/gl/xsize.h
index 1ec78e77..ee9c5680 100644
--- a/gl/xsize.h
+++ b/gl/xsize.h
@@ -1,6 +1,6 @@
1/* xsize.h -- Checked size_t computations. 1/* xsize.h -- Checked size_t computations.
2 2
3 Copyright (C) 2003, 2008-2023 Free Software Foundation, Inc. 3 Copyright (C) 2003, 2008-2025 Free Software Foundation, Inc.
4 4
5 This file is free software: you can redistribute it and/or modify 5 This file is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as 6 it under the terms of the GNU Lesser General Public License as
@@ -18,10 +18,15 @@
18#ifndef _XSIZE_H 18#ifndef _XSIZE_H
19#define _XSIZE_H 19#define _XSIZE_H
20 20
21/* This file uses _GL_INLINE_HEADER_BEGIN, _GL_INLINE, HAVE_STDINT_H. */
22#if !_GL_CONFIG_H_INCLUDED
23 #error "Please include config.h first."
24#endif
25
21/* Get size_t. */ 26/* Get size_t. */
22#include <stddef.h> 27#include <stddef.h>
23 28
24/* Get SIZE_MAX. */ 29/* Get INT_MAX, SIZE_MAX. */
25#include <limits.h> 30#include <limits.h>
26#if HAVE_STDINT_H 31#if HAVE_STDINT_H
27# include <stdint.h> 32# include <stdint.h>
@@ -30,14 +35,16 @@
30/* Get ATTRIBUTE_PURE. */ 35/* Get ATTRIBUTE_PURE. */
31#include "attribute.h" 36#include "attribute.h"
32 37
33#ifndef _GL_INLINE_HEADER_BEGIN
34 #error "Please include config.h first."
35#endif
36_GL_INLINE_HEADER_BEGIN 38_GL_INLINE_HEADER_BEGIN
37#ifndef XSIZE_INLINE 39#ifndef XSIZE_INLINE
38# define XSIZE_INLINE _GL_INLINE 40# define XSIZE_INLINE _GL_INLINE
39#endif 41#endif
40 42
43#ifdef __cplusplus
44extern "C" {
45#endif
46
47
41/* The size of memory objects is often computed through expressions of 48/* The size of memory objects is often computed through expressions of
42 type size_t. Example: 49 type size_t. Example:
43 void* p = malloc (header_size + n * element_size). 50 void* p = malloc (header_size + n * element_size).
@@ -54,7 +61,8 @@ _GL_INLINE_HEADER_BEGIN
54 void *p = (size_in_bounds_p (size) ? malloc (size) : NULL); 61 void *p = (size_in_bounds_p (size) ? malloc (size) : NULL);
55*/ 62*/
56 63
57/* Convert an arbitrary value >= 0 to type size_t. */ 64/* Convert an arbitrary N >= 0 to type size_t.
65 N should not have side effects. */
58#define xcast_size_t(N) \ 66#define xcast_size_t(N) \
59 ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX) 67 ((N) <= SIZE_MAX ? (size_t) (N) : SIZE_MAX)
60 68
@@ -62,8 +70,15 @@ _GL_INLINE_HEADER_BEGIN
62XSIZE_INLINE size_t ATTRIBUTE_PURE 70XSIZE_INLINE size_t ATTRIBUTE_PURE
63xsum (size_t size1, size_t size2) 71xsum (size_t size1, size_t size2)
64{ 72{
65 size_t sum = size1 + size2; 73 if (INT_MAX < SIZE_MAX)
66 return (sum >= size1 ? sum : SIZE_MAX); 74 {
75 /* Optimize for the common case where size_t arithmetic wraps
76 around without undefined behavior. */
77 size_t sum = size1 + size2;
78 return size1 <= sum ? sum : SIZE_MAX;
79 }
80
81 return size1 <= SIZE_MAX - size2 ? size1 + size2 : SIZE_MAX;
67} 82}
68 83
69/* Sum of three sizes, with overflow check. */ 84/* Sum of three sizes, with overflow check. */
@@ -91,6 +106,8 @@ xmax (size_t size1, size_t size2)
91 106
92/* Multiplication of a count with an element size, with overflow check. 107/* Multiplication of a count with an element size, with overflow check.
93 The count must be >= 0 and the element size must be > 0. 108 The count must be >= 0 and the element size must be > 0.
109 Arguments should not have side effects.
110 The element size's type should be no wider than size_t.
94 This is a macro, not a function, so that it works correctly even 111 This is a macro, not a function, so that it works correctly even
95 when N is of a wider type and N > SIZE_MAX. */ 112 when N is of a wider type and N > SIZE_MAX. */
96#define xtimes(N, ELSIZE) \ 113#define xtimes(N, ELSIZE) \
@@ -103,6 +120,11 @@ xmax (size_t size1, size_t size2)
103#define size_in_bounds_p(SIZE) \ 120#define size_in_bounds_p(SIZE) \
104 ((SIZE) != SIZE_MAX) 121 ((SIZE) != SIZE_MAX)
105 122
123
124#ifdef __cplusplus
125}
126#endif
127
106_GL_INLINE_HEADER_END 128_GL_INLINE_HEADER_END
107 129
108#endif /* _XSIZE_H */ 130#endif /* _XSIZE_H */