From 3dcc12b30a80cac583349b201ff9673ab7295e88 Mon Sep 17 00:00:00 2001 From: Daniel Pouzzner Date: Wed, 4 Dec 2024 18:32:27 -0600 Subject: [PATCH] wolfssl/wolfcrypt/types.h and wolfssl/wolfcrypt/hash.h: define WOLF_AGG_DUMMY_MEMBER, pivoting on HAVE_EMPTY_AGGREGATES, and use WOLF_AGG_DUMMY_MEMBER in wc_Hashes. --- wolfssl/wolfcrypt/hash.h | 1 + wolfssl/wolfcrypt/types.h | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/wolfssl/wolfcrypt/hash.h b/wolfssl/wolfcrypt/hash.h index edbc949bc..ee001a98b 100644 --- a/wolfssl/wolfcrypt/hash.h +++ b/wolfssl/wolfcrypt/hash.h @@ -119,6 +119,7 @@ typedef union { #ifdef WOLFSSL_SM3 wc_Sm3 sm3; #endif + WOLF_AGG_DUMMY_MEMBER; } wc_Hashes; #ifndef NO_HASH_WRAPPER diff --git a/wolfssl/wolfcrypt/types.h b/wolfssl/wolfcrypt/types.h index d2a9dc44f..a90a9fe16 100644 --- a/wolfssl/wolfcrypt/types.h +++ b/wolfssl/wolfcrypt/types.h @@ -135,6 +135,44 @@ decouple library dependencies with standard string, memory and so on. #endif #endif + #ifndef HAVE_EMPTY_AGGREGATES + /* The C standards don't define empty aggregates, but gcc and clang do. + * We need to accommodate them for one of the same reasons C++ does -- + * templates that conditionally result in empty aggregates, e.g. in + * hash.h. + */ + #if !defined(WOLF_C89) && defined(__GNUC__) && \ + !defined(__STRICT_ANSI__) && \ + HAVE_ANONYMOUS_INLINE_AGGREGATES + 0 == 1 + #define HAVE_EMPTY_AGGREGATES 1 + #else + #define HAVE_EMPTY_AGGREGATES 0 + #endif + #endif + + #define _WOLF_AGG_DUMMY_MEMBER_HELPER2(a, b, c) a ## b ## c + #define _WOLF_AGG_DUMMY_MEMBER_HELPER(a, b, c) _WOLF_AGG_DUMMY_MEMBER_HELPER2(a, b, c) + #if HAVE_EMPTY_AGGREGATES + 0 == 1 + /* swallow the semicolon with a zero-sized array (language extension + * specific to gcc/clang). + */ + #define WOLF_AGG_DUMMY_MEMBER \ + struct { \ + PRAGMA_GCC_DIAG_PUSH \ + PRAGMA_GCC("GCC diagnostic ignored \"-Wpedantic\"") \ + PRAGMA_CLANG_DIAG_PUSH \ + PRAGMA_CLANG("clang diagnostic ignored \"-Wzero-length-array\"") \ + byte _WOLF_AGG_DUMMY_MEMBER_HELPER(_wolf_L, __LINE__, _agg_dummy_member)[0]; \ + PRAGMA_CLANG_DIAG_POP \ + PRAGMA_GCC_DIAG_POP \ + } + #else + /* Use a single byte with a constructed name as a dummy member -- these + * are the standard semantics of an empty structure in C++. + */ + #define WOLF_AGG_DUMMY_MEMBER char _WOLF_AGG_DUMMY_MEMBER_HELPER(_wolf_L, __LINE__, _agg_dummy_member) + #endif + /* helpers for stringifying the expanded value of a macro argument rather * than its literal text: */