LCOV - code coverage report
Current view: top level - externals/mbedtls/library - common.h (source / functions) Coverage Total Hit
Test: lcov.info Lines: 63.6 % 11 7
Test Date: 2026-01-29 09:48:10 Functions: 0.0 % 2 0
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 80.0 % 20 16

             Branch data     Line data    Source code
       1                 :             : /**
       2                 :             :  * \file common.h
       3                 :             :  *
       4                 :             :  * \brief Utility macros for internal use in the library
       5                 :             :  */
       6                 :             : /*
       7                 :             :  *  Copyright The Mbed TLS Contributors
       8                 :             :  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
       9                 :             :  */
      10                 :             : 
      11                 :             : #ifndef MBEDTLS_LIBRARY_COMMON_H
      12                 :             : #define MBEDTLS_LIBRARY_COMMON_H
      13                 :             : 
      14                 :             : #include "mbedtls/build_info.h"
      15                 :             : #include "alignment.h"
      16                 :             : 
      17                 :             : #include <assert.h>
      18                 :             : #include <stddef.h>
      19                 :             : #include <stdint.h>
      20                 :             : #include <stddef.h>
      21                 :             : 
      22                 :             : #if defined(__ARM_NEON)
      23                 :             : #include <arm_neon.h>
      24                 :             : #define MBEDTLS_HAVE_NEON_INTRINSICS
      25                 :             : #elif defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64)
      26                 :             : #include <arm64_neon.h>
      27                 :             : #define MBEDTLS_HAVE_NEON_INTRINSICS
      28                 :             : #endif
      29                 :             : 
      30                 :             : /** Helper to define a function as static except when building invasive tests.
      31                 :             :  *
      32                 :             :  * If a function is only used inside its own source file and should be
      33                 :             :  * declared `static` to allow the compiler to optimize for code size,
      34                 :             :  * but that function has unit tests, define it with
      35                 :             :  * ```
      36                 :             :  * MBEDTLS_STATIC_TESTABLE int mbedtls_foo(...) { ... }
      37                 :             :  * ```
      38                 :             :  * and declare it in a header in the `library/` directory with
      39                 :             :  * ```
      40                 :             :  * #if defined(MBEDTLS_TEST_HOOKS)
      41                 :             :  * int mbedtls_foo(...);
      42                 :             :  * #endif
      43                 :             :  * ```
      44                 :             :  */
      45                 :             : #if defined(MBEDTLS_TEST_HOOKS)
      46                 :             : #define MBEDTLS_STATIC_TESTABLE
      47                 :             : #else
      48                 :             : #define MBEDTLS_STATIC_TESTABLE static
      49                 :             : #endif
      50                 :             : 
      51                 :             : #if defined(MBEDTLS_TEST_HOOKS)
      52                 :             : extern void (*mbedtls_test_hook_test_fail)(const char *test, int line, const char *file);
      53                 :             : #define MBEDTLS_TEST_HOOK_TEST_ASSERT(TEST) \
      54                 :             :     do { \
      55                 :             :         if ((!(TEST)) && ((*mbedtls_test_hook_test_fail) != NULL)) \
      56                 :             :         { \
      57                 :             :             (*mbedtls_test_hook_test_fail)( #TEST, __LINE__, __FILE__); \
      58                 :             :         } \
      59                 :             :     } while (0)
      60                 :             : #else
      61                 :             : #define MBEDTLS_TEST_HOOK_TEST_ASSERT(TEST)
      62                 :             : #endif /* defined(MBEDTLS_TEST_HOOKS) */
      63                 :             : 
      64                 :             : /** \def ARRAY_LENGTH
      65                 :             :  * Return the number of elements of a static or stack array.
      66                 :             :  *
      67                 :             :  * \param array         A value of array (not pointer) type.
      68                 :             :  *
      69                 :             :  * \return The number of elements of the array.
      70                 :             :  */
      71                 :             : /* A correct implementation of ARRAY_LENGTH, but which silently gives
      72                 :             :  * a nonsensical result if called with a pointer rather than an array. */
      73                 :             : #define ARRAY_LENGTH_UNSAFE(array)            \
      74                 :             :     (sizeof(array) / sizeof(*(array)))
      75                 :             : 
      76                 :             : #if defined(__GNUC__)
      77                 :             : /* Test if arg and &(arg)[0] have the same type. This is true if arg is
      78                 :             :  * an array but not if it's a pointer. */
      79                 :             : #define IS_ARRAY_NOT_POINTER(arg)                                     \
      80                 :             :     (!__builtin_types_compatible_p(__typeof__(arg),                \
      81                 :             :                                    __typeof__(&(arg)[0])))
      82                 :             : /* A compile-time constant with the value 0. If `const_expr` is not a
      83                 :             :  * compile-time constant with a nonzero value, cause a compile-time error. */
      84                 :             : #define STATIC_ASSERT_EXPR(const_expr)                                \
      85                 :             :     (0 && sizeof(struct { unsigned int STATIC_ASSERT : 1 - 2 * !(const_expr); }))
      86                 :             : 
      87                 :             : /* Return the scalar value `value` (possibly promoted). This is a compile-time
      88                 :             :  * constant if `value` is. `condition` must be a compile-time constant.
      89                 :             :  * If `condition` is false, arrange to cause a compile-time error. */
      90                 :             : #define STATIC_ASSERT_THEN_RETURN(condition, value)   \
      91                 :             :     (STATIC_ASSERT_EXPR(condition) ? 0 : (value))
      92                 :             : 
      93                 :             : #define ARRAY_LENGTH(array)                                           \
      94                 :             :     (STATIC_ASSERT_THEN_RETURN(IS_ARRAY_NOT_POINTER(array),         \
      95                 :             :                                ARRAY_LENGTH_UNSAFE(array)))
      96                 :             : 
      97                 :             : #else
      98                 :             : /* If we aren't sure the compiler supports our non-standard tricks,
      99                 :             :  * fall back to the unsafe implementation. */
     100                 :             : #define ARRAY_LENGTH(array) ARRAY_LENGTH_UNSAFE(array)
     101                 :             : #endif
     102                 :             : /** Allow library to access its structs' private members.
     103                 :             :  *
     104                 :             :  * Although structs defined in header files are publicly available,
     105                 :             :  * their members are private and should not be accessed by the user.
     106                 :             :  */
     107                 :             : #define MBEDTLS_ALLOW_PRIVATE_ACCESS
     108                 :             : 
     109                 :             : /**
     110                 :             :  * \brief       Securely zeroize a buffer then free it.
     111                 :             :  *
     112                 :             :  *              Similar to making consecutive calls to
     113                 :             :  *              \c mbedtls_platform_zeroize() and \c mbedtls_free(), but has
     114                 :             :  *              code size savings, and potential for optimisation in the future.
     115                 :             :  *
     116                 :             :  *              Guaranteed to be a no-op if \p buf is \c NULL and \p len is 0.
     117                 :             :  *
     118                 :             :  * \param buf   Buffer to be zeroized then freed.
     119                 :             :  * \param len   Length of the buffer in bytes
     120                 :             :  */
     121                 :             : void mbedtls_zeroize_and_free(void *buf, size_t len);
     122                 :             : 
     123                 :             : /** Return an offset into a buffer.
     124                 :             :  *
     125                 :             :  * This is just the addition of an offset to a pointer, except that this
     126                 :             :  * function also accepts an offset of 0 into a buffer whose pointer is null.
     127                 :             :  * (`p + n` has undefined behavior when `p` is null, even when `n == 0`.
     128                 :             :  * A null pointer is a valid buffer pointer when the size is 0, for example
     129                 :             :  * as the result of `malloc(0)` on some platforms.)
     130                 :             :  *
     131                 :             :  * \param p     Pointer to a buffer of at least n bytes.
     132                 :             :  *              This may be \p NULL if \p n is zero.
     133                 :             :  * \param n     An offset in bytes.
     134                 :             :  * \return      Pointer to offset \p n in the buffer \p p.
     135                 :             :  *              Note that this is only a valid pointer if the size of the
     136                 :             :  *              buffer is at least \p n + 1.
     137                 :             :  */
     138                 :           0 : static inline unsigned char *mbedtls_buffer_offset(
     139                 :             :     unsigned char *p, size_t n)
     140                 :             : {
     141         [ #  # ]:           0 :     return p == NULL ? NULL : p + n;
     142                 :             : }
     143                 :             : 
     144                 :             : /** Return an offset into a read-only buffer.
     145                 :             :  *
     146                 :             :  * Similar to mbedtls_buffer_offset(), but for const pointers.
     147                 :             :  *
     148                 :             :  * \param p     Pointer to a buffer of at least n bytes.
     149                 :             :  *              This may be \p NULL if \p n is zero.
     150                 :             :  * \param n     An offset in bytes.
     151                 :             :  * \return      Pointer to offset \p n in the buffer \p p.
     152                 :             :  *              Note that this is only a valid pointer if the size of the
     153                 :             :  *              buffer is at least \p n + 1.
     154                 :             :  */
     155                 :           0 : static inline const unsigned char *mbedtls_buffer_offset_const(
     156                 :             :     const unsigned char *p, size_t n)
     157                 :             : {
     158         [ #  # ]:           0 :     return p == NULL ? NULL : p + n;
     159                 :             : }
     160                 :             : 
     161                 :             : /* Always inline mbedtls_xor() for similar reasons as mbedtls_xor_no_simd(). */
     162                 :             : #if defined(__IAR_SYSTEMS_ICC__)
     163                 :             : #pragma inline = forced
     164                 :             : #elif defined(__GNUC__)
     165                 :             : __attribute__((always_inline))
     166                 :             : #endif
     167                 :             : /**
     168                 :             :  * Perform a fast block XOR operation, such that
     169                 :             :  * r[i] = a[i] ^ b[i] where 0 <= i < n
     170                 :             :  *
     171                 :             :  * \param   r Pointer to result (buffer of at least \p n bytes). \p r
     172                 :             :  *            may be equal to either \p a or \p b, but behaviour when
     173                 :             :  *            it overlaps in other ways is undefined.
     174                 :             :  * \param   a Pointer to input (buffer of at least \p n bytes)
     175                 :             :  * \param   b Pointer to input (buffer of at least \p n bytes)
     176                 :             :  * \param   n Number of bytes to process.
     177                 :             :  *
     178                 :             :  * \note      Depending on the situation, it may be faster to use either mbedtls_xor() or
     179                 :             :  *            mbedtls_xor_no_simd() (these are functionally equivalent).
     180                 :             :  *            If the result is used immediately after the xor operation in non-SIMD code (e.g, in
     181                 :             :  *            AES-CBC), there may be additional latency to transfer the data from SIMD to scalar
     182                 :             :  *            registers, and in this case, mbedtls_xor_no_simd() may be faster. In other cases where
     183                 :             :  *            the result is not used immediately (e.g., in AES-CTR), mbedtls_xor() may be faster.
     184                 :             :  *            For targets without SIMD support, they will behave the same.
     185                 :             :  */
     186                 :         319 : static inline void mbedtls_xor(unsigned char *r,
     187                 :             :                                const unsigned char *a,
     188                 :             :                                const unsigned char *b,
     189                 :             :                                size_t n)
     190                 :             : {
     191                 :         319 :     size_t i = 0;
     192                 :             : #if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
     193                 :             : #if defined(MBEDTLS_HAVE_NEON_INTRINSICS) && \
     194                 :             :     (!(defined(MBEDTLS_COMPILER_IS_GCC) && MBEDTLS_GCC_VERSION < 70300))
     195                 :             :     /* Old GCC versions generate a warning here, so disable the NEON path for these compilers */
     196                 :             :     for (; (i + 16) <= n; i += 16) {
     197                 :             :         uint8x16_t v1 = vld1q_u8(a + i);
     198                 :             :         uint8x16_t v2 = vld1q_u8(b + i);
     199                 :             :         uint8x16_t x = veorq_u8(v1, v2);
     200                 :             :         vst1q_u8(r + i, x);
     201                 :             :     }
     202                 :             : #if defined(__IAR_SYSTEMS_ICC__)
     203                 :             :     /* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case
     204                 :             :      * where n is a constant multiple of 16.
     205                 :             :      * For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time
     206                 :             :      * constant, and is a very small perf regression if n is not a compile-time constant. */
     207                 :             :     if (n % 16 == 0) {
     208                 :             :         return;
     209                 :             :     }
     210                 :             : #endif
     211                 :             : #elif defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64)
     212                 :             :     /* This codepath probably only makes sense on architectures with 64-bit registers */
     213                 :             :     for (; (i + 8) <= n; i += 8) {
     214                 :             :         uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i);
     215                 :             :         mbedtls_put_unaligned_uint64(r + i, x);
     216                 :             :     }
     217                 :             : #if defined(__IAR_SYSTEMS_ICC__)
     218                 :             :     if (n % 8 == 0) {
     219                 :             :         return;
     220                 :             :     }
     221                 :             : #endif
     222                 :             : #else
     223   [ +  +  +  +  :        1546 :     for (; (i + 4) <= n; i += 4) {
             +  +  +  + ]
     224                 :        1212 :         uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i);
     225                 :        1212 :         mbedtls_put_unaligned_uint32(r + i, x);
     226                 :             :     }
     227                 :             : #if defined(__IAR_SYSTEMS_ICC__)
     228                 :             :     if (n % 4 == 0) {
     229                 :             :         return;
     230                 :             :     }
     231                 :             : #endif
     232                 :             : #endif
     233                 :             : #endif
     234   [ +  +  +  +  :         601 :     for (; i < n; i++) {
             +  +  +  + ]
     235                 :         267 :         r[i] = a[i] ^ b[i];
     236                 :             :     }
     237                 :             : }
     238                 :             : 
     239                 :             : /* Always inline mbedtls_xor_no_simd() as we see significant perf regressions when it does not get
     240                 :             :  * inlined (e.g., observed about 3x perf difference in gcm_mult_largetable with gcc 7 - 12) */
     241                 :             : #if defined(__IAR_SYSTEMS_ICC__)
     242                 :             : #pragma inline = forced
     243                 :             : #elif defined(__GNUC__)
     244                 :             : __attribute__((always_inline))
     245                 :             : #endif
     246                 :             : /**
     247                 :             :  * Perform a fast block XOR operation, such that
     248                 :             :  * r[i] = a[i] ^ b[i] where 0 <= i < n
     249                 :             :  *
     250                 :             :  * In some situations, this can perform better than mbedtls_xor() (e.g., it's about 5%
     251                 :             :  * better in AES-CBC).
     252                 :             :  *
     253                 :             :  * \param   r Pointer to result (buffer of at least \p n bytes). \p r
     254                 :             :  *            may be equal to either \p a or \p b, but behaviour when
     255                 :             :  *            it overlaps in other ways is undefined.
     256                 :             :  * \param   a Pointer to input (buffer of at least \p n bytes)
     257                 :             :  * \param   b Pointer to input (buffer of at least \p n bytes)
     258                 :             :  * \param   n Number of bytes to process.
     259                 :             :  *
     260                 :             :  * \note      Depending on the situation, it may be faster to use either mbedtls_xor() or
     261                 :             :  *            mbedtls_xor_no_simd() (these are functionally equivalent).
     262                 :             :  *            If the result is used immediately after the xor operation in non-SIMD code (e.g, in
     263                 :             :  *            AES-CBC), there may be additional latency to transfer the data from SIMD to scalar
     264                 :             :  *            registers, and in this case, mbedtls_xor_no_simd() may be faster. In other cases where
     265                 :             :  *            the result is not used immediately (e.g., in AES-CTR), mbedtls_xor() may be faster.
     266                 :             :  *            For targets without SIMD support, they will behave the same.
     267                 :             :  */
     268                 :             : static inline void mbedtls_xor_no_simd(unsigned char *r,
     269                 :             :                                        const unsigned char *a,
     270                 :             :                                        const unsigned char *b,
     271                 :             :                                        size_t n)
     272                 :             : {
     273                 :             :     size_t i = 0;
     274                 :             : #if defined(MBEDTLS_EFFICIENT_UNALIGNED_ACCESS)
     275                 :             : #if defined(MBEDTLS_ARCH_IS_X64) || defined(MBEDTLS_ARCH_IS_ARM64)
     276                 :             :     /* This codepath probably only makes sense on architectures with 64-bit registers */
     277                 :             :     for (; (i + 8) <= n; i += 8) {
     278                 :             :         uint64_t x = mbedtls_get_unaligned_uint64(a + i) ^ mbedtls_get_unaligned_uint64(b + i);
     279                 :             :         mbedtls_put_unaligned_uint64(r + i, x);
     280                 :             :     }
     281                 :             : #if defined(__IAR_SYSTEMS_ICC__)
     282                 :             :     /* This if statement helps some compilers (e.g., IAR) optimise out the byte-by-byte tail case
     283                 :             :      * where n is a constant multiple of 8.
     284                 :             :      * For other compilers (e.g. recent gcc and clang) it makes no difference if n is a compile-time
     285                 :             :      * constant, and is a very small perf regression if n is not a compile-time constant. */
     286                 :             :     if (n % 8 == 0) {
     287                 :             :         return;
     288                 :             :     }
     289                 :             : #endif
     290                 :             : #else
     291                 :             :     for (; (i + 4) <= n; i += 4) {
     292                 :             :         uint32_t x = mbedtls_get_unaligned_uint32(a + i) ^ mbedtls_get_unaligned_uint32(b + i);
     293                 :             :         mbedtls_put_unaligned_uint32(r + i, x);
     294                 :             :     }
     295                 :             : #if defined(__IAR_SYSTEMS_ICC__)
     296                 :             :     if (n % 4 == 0) {
     297                 :             :         return;
     298                 :             :     }
     299                 :             : #endif
     300                 :             : #endif
     301                 :             : #endif
     302                 :             :     for (; i < n; i++) {
     303                 :             :         r[i] = a[i] ^ b[i];
     304                 :             :     }
     305                 :             : }
     306                 :             : 
     307                 :             : /* Fix MSVC C99 compatible issue
     308                 :             :  *      MSVC support __func__ from visual studio 2015( 1900 )
     309                 :             :  *      Use MSVC predefine macro to avoid name check fail.
     310                 :             :  */
     311                 :             : #if (defined(_MSC_VER) && (_MSC_VER <= 1900))
     312                 :             : #define /*no-check-names*/ __func__ __FUNCTION__
     313                 :             : #endif
     314                 :             : 
     315                 :             : /* Define `asm` for compilers which don't define it. */
     316                 :             : /* *INDENT-OFF* */
     317                 :             : #ifndef asm
     318                 :             : #if defined(__IAR_SYSTEMS_ICC__)
     319                 :             : #define asm __asm
     320                 :             : #else
     321                 :             : #define asm __asm__
     322                 :             : #endif
     323                 :             : #endif
     324                 :             : /* *INDENT-ON* */
     325                 :             : 
     326                 :             : /*
     327                 :             :  * Define the constraint used for read-only pointer operands to aarch64 asm.
     328                 :             :  *
     329                 :             :  * This is normally the usual "r", but for aarch64_32 (aka ILP32,
     330                 :             :  * as found in watchos), "p" is required to avoid warnings from clang.
     331                 :             :  *
     332                 :             :  * Note that clang does not recognise '+p' or '=p', and armclang
     333                 :             :  * does not recognise 'p' at all. Therefore, to update a pointer from
     334                 :             :  * aarch64 assembly, it is necessary to use something like:
     335                 :             :  *
     336                 :             :  * uintptr_t uptr = (uintptr_t) ptr;
     337                 :             :  * asm( "ldr x4, [%x0], #8" ... : "+r" (uptr) : : )
     338                 :             :  * ptr = (void*) uptr;
     339                 :             :  *
     340                 :             :  * Note that the "x" in "%x0" is neccessary; writing "%0" will cause warnings.
     341                 :             :  */
     342                 :             : #if defined(__aarch64__) && defined(MBEDTLS_HAVE_ASM)
     343                 :             : #if UINTPTR_MAX == 0xfffffffful
     344                 :             : /* ILP32: Specify the pointer operand slightly differently, as per #7787. */
     345                 :             : #define MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT "p"
     346                 :             : #elif UINTPTR_MAX == 0xfffffffffffffffful
     347                 :             : /* Normal case (64-bit pointers): use "r" as the constraint for pointer operands to asm */
     348                 :             : #define MBEDTLS_ASM_AARCH64_PTR_CONSTRAINT "r"
     349                 :             : #else
     350                 :             : #error "Unrecognised pointer size for aarch64"
     351                 :             : #endif
     352                 :             : #endif
     353                 :             : 
     354                 :             : /* Always provide a static assert macro, so it can be used unconditionally.
     355                 :             :  * It does nothing on systems where we don't know how to define a static assert.
     356                 :             :  */
     357                 :             : /* Can't use the C11-style `defined(static_assert)` on FreeBSD, since it
     358                 :             :  * defines static_assert even with -std=c99, but then complains about it.
     359                 :             :  */
     360                 :             : #if defined(static_assert) && !defined(__FreeBSD__)
     361                 :             : #define MBEDTLS_STATIC_ASSERT(expr, msg)    static_assert(expr, msg)
     362                 :             : #else
     363                 :             : /* Make sure `MBEDTLS_STATIC_ASSERT(expr, msg);` is valid both inside and
     364                 :             :  * outside a function. We choose a struct declaration, which can be repeated
     365                 :             :  * any number of times and does not need a matching definition. */
     366                 :             : #define MBEDTLS_STATIC_ASSERT(expr, msg)                                \
     367                 :             :     struct ISO_C_does_not_allow_extra_semicolon_outside_of_a_function
     368                 :             : #endif
     369                 :             : 
     370                 :             : #if defined(__has_builtin)
     371                 :             : #define MBEDTLS_HAS_BUILTIN(x) __has_builtin(x)
     372                 :             : #else
     373                 :             : #define MBEDTLS_HAS_BUILTIN(x) 0
     374                 :             : #endif
     375                 :             : 
     376                 :             : /* Define compiler branch hints */
     377                 :             : #if MBEDTLS_HAS_BUILTIN(__builtin_expect)
     378                 :             : #define MBEDTLS_LIKELY(x)       __builtin_expect(!!(x), 1)
     379                 :             : #define MBEDTLS_UNLIKELY(x)     __builtin_expect(!!(x), 0)
     380                 :             : #else
     381                 :             : #define MBEDTLS_LIKELY(x)       x
     382                 :             : #define MBEDTLS_UNLIKELY(x)     x
     383                 :             : #endif
     384                 :             : 
     385                 :             : /* MBEDTLS_ASSUME may be used to provide additional information to the compiler
     386                 :             :  * which can result in smaller code-size. */
     387                 :             : #if MBEDTLS_HAS_BUILTIN(__builtin_assume)
     388                 :             : /* clang provides __builtin_assume */
     389                 :             : #define MBEDTLS_ASSUME(x)       __builtin_assume(x)
     390                 :             : #elif MBEDTLS_HAS_BUILTIN(__builtin_unreachable)
     391                 :             : /* gcc and IAR can use __builtin_unreachable */
     392                 :             : #define MBEDTLS_ASSUME(x)       do { if (!(x)) __builtin_unreachable(); } while (0)
     393                 :             : #elif defined(_MSC_VER)
     394                 :             : /* Supported by MSVC since VS 2005 */
     395                 :             : #define MBEDTLS_ASSUME(x)       __assume(x)
     396                 :             : #else
     397                 :             : #define MBEDTLS_ASSUME(x)       do { } while (0)
     398                 :             : #endif
     399                 :             : 
     400                 :             : /* For gcc -Os, override with -O2 for a given function.
     401                 :             :  *
     402                 :             :  * This will not affect behaviour for other optimisation settings, e.g. -O0.
     403                 :             :  */
     404                 :             : #if defined(MBEDTLS_COMPILER_IS_GCC) && defined(__OPTIMIZE_SIZE__)
     405                 :             : #define MBEDTLS_OPTIMIZE_FOR_PERFORMANCE __attribute__((optimize("-O2")))
     406                 :             : #else
     407                 :             : #define MBEDTLS_OPTIMIZE_FOR_PERFORMANCE
     408                 :             : #endif
     409                 :             : 
     410                 :             : /* Suppress compiler warnings for unused functions and variables. */
     411                 :             : #if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__has_attribute)
     412                 :             : #    if __has_attribute(unused)
     413                 :             : #        define MBEDTLS_MAYBE_UNUSED __attribute__((unused))
     414                 :             : #    endif
     415                 :             : #endif
     416                 :             : #if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__GNUC__)
     417                 :             : #    define MBEDTLS_MAYBE_UNUSED __attribute__((unused))
     418                 :             : #endif
     419                 :             : #if !defined(MBEDTLS_MAYBE_UNUSED) && defined(__IAR_SYSTEMS_ICC__) && defined(__VER__)
     420                 :             : /* IAR does support __attribute__((unused)), but only if the -e flag (extended language support)
     421                 :             :  * is given; the pragma always works.
     422                 :             :  * Unfortunately the pragma affects the rest of the file where it is used, but this is harmless.
     423                 :             :  * Check for version 5.2 or later - this pragma may be supported by earlier versions, but I wasn't
     424                 :             :  * able to find documentation).
     425                 :             :  */
     426                 :             : #    if (__VER__ >= 5020000)
     427                 :             : #        define MBEDTLS_MAYBE_UNUSED _Pragma("diag_suppress=Pe177")
     428                 :             : #    endif
     429                 :             : #endif
     430                 :             : #if !defined(MBEDTLS_MAYBE_UNUSED) && defined(_MSC_VER)
     431                 :             : #    define MBEDTLS_MAYBE_UNUSED __pragma(warning(suppress:4189))
     432                 :             : #endif
     433                 :             : #if !defined(MBEDTLS_MAYBE_UNUSED)
     434                 :             : #    define MBEDTLS_MAYBE_UNUSED
     435                 :             : #endif
     436                 :             : 
     437                 :             : /* GCC >= 15 has a warning 'unterminated-string-initialization' which complains if you initialize
     438                 :             :  * a string into an array without space for a terminating NULL character. In some places in the
     439                 :             :  * codebase this behaviour is intended, so we add the macro MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING
     440                 :             :  * to suppress the warning in these places.
     441                 :             :  */
     442                 :             : #if defined(__has_attribute)
     443                 :             : #if __has_attribute(nonstring)
     444                 :             : #define MBEDTLS_HAS_ATTRIBUTE_NONSTRING
     445                 :             : #endif /* __has_attribute(nonstring) */
     446                 :             : #endif /* __has_attribute */
     447                 :             : #if defined(MBEDTLS_HAS_ATTRIBUTE_NONSTRING)
     448                 :             : #define MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING __attribute__((nonstring))
     449                 :             : #else
     450                 :             : #define MBEDTLS_ATTRIBUTE_UNTERMINATED_STRING
     451                 :             : #endif /* MBEDTLS_HAS_ATTRIBUTE_NONSTRING */
     452                 :             : 
     453                 :             : #endif /* MBEDTLS_LIBRARY_COMMON_H */
        

Generated by: LCOV version 2.0-1