microsoft / SymCrypt

Cryptographic library
MIT License
660 stars 68 forks source link

LLVM Clang and GCC Error: request for member 'm128i_u64' in something not a structure or union #29

Closed ajkhoury closed 11 months ago

ajkhoury commented 1 year ago

Building on Windows or Ubuntu 22.10 with LLVM Clang 15 or GCC 12.2.0, the following error occurs when attempting to compile lib/sha512.c:

F:/Projects/Bootlie/contrib/SymCrypt/lib/sha512.c:1036:33: error: request for member 'm128i_u64' in something not a structure or union

This error occurs because Clang and GCC define the 128-bit XMM data types as typedef'd vectors rather than as a struct/union like defined in the UCRT. I.e. Clang defines these types as such: typedef long long __m128i __attribute__((__vector_size__(16), __aligned__(16)));

A quick fix for little endian systems is to simply pointer-cast a given 128-bit XMM data type variable to an unsigned 64-bit integer.

Please consider adding a simple compiler check to pointer-cast to an unsigned __int64 type for Clang and GCC toolchains. Below is a patch:

diff --git lib/sha512.c lib/sha512.c
index 745ef24..f4abe4a 100644
--- lib/sha512.c
+++ lib/sha512.c
@@ -1030,7 +1030,11 @@ SymCryptSha512AppendBlocks_ull3(
 #define XMMROR( _a, _n ) _mm_xor_si128( _mm_slli_epi64( (_a), 64-(_n)), _mm_srli_epi64( (_a), (_n)) )
 #define XMMSHR( _a, _n ) _mm_srli_epi64((_a), (_n))
 #define XMMXOR( _a, _b ) _mm_xor_si128((_a), (_b))
+#if defined(__clang__) || defined(__GNUC__)
+#define XMMTO_UINT64( _a ) *(unsigned __int64 *)(&(_a))
+#else
 #define XMMTO_UINT64( _a ) ((_a).m128i_u64[0])
+#endif

 #define XMMMAJ( x, y, z )  XMMOR( XMMAND( XMMOR( (z), (y)), (x)), XMMAND( (z), (y) ) )
 #define XMMCH(  x, y, z )  XMMXOR( XMMAND( XMMXOR( (z), (y) ), (x)), (z))
mlindgren commented 1 year ago

Thanks for your report. We're looking into this.

mlindgren commented 11 months ago

Fixed by 770f81ffb4df736c40f5c4639b058ea812e7abba