diff --git a/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h b/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h index c56fe0c1e8..91907c0285 100644 --- a/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h +++ b/modules/juce_audio_basics/buffers/juce_AudioDataConverters.h @@ -104,7 +104,7 @@ public: inline float getAsFloatBE() const noexcept { return getAsFloatLE(); } inline void setAsFloatLE (float newValue) noexcept { *data = (int8) jlimit ((int) -maxValue, (int) maxValue, roundToInt (newValue * (1.0 + maxValue))); } inline void setAsFloatBE (float newValue) noexcept { setAsFloatLE (newValue); } - inline int32 getAsInt32LE() const noexcept { return (int) (*data << 24); } + inline int32 getAsInt32LE() const noexcept { return (int) (*((uint8*) data) << 24); } inline int32 getAsInt32BE() const noexcept { return getAsInt32LE(); } inline void setAsInt32LE (int newValue) noexcept { *data = (int8) (newValue >> 24); } inline void setAsInt32BE (int newValue) noexcept { setAsInt32LE (newValue); } @@ -129,7 +129,7 @@ public: inline float getAsFloatBE() const noexcept { return getAsFloatLE(); } inline void setAsFloatLE (float newValue) noexcept { *data = (uint8) jlimit (0, 255, 128 + roundToInt (newValue * (1.0 + maxValue))); } inline void setAsFloatBE (float newValue) noexcept { setAsFloatLE (newValue); } - inline int32 getAsInt32LE() const noexcept { return (int) ((*data - 128) << 24); } + inline int32 getAsInt32LE() const noexcept { return (int) (((uint8) (*data - 128)) << 24); } inline int32 getAsInt32BE() const noexcept { return getAsInt32LE(); } inline void setAsInt32LE (int newValue) noexcept { *data = (uint8) (128 + (newValue >> 24)); } inline void setAsInt32BE (int newValue) noexcept { setAsInt32LE (newValue); } @@ -150,13 +150,13 @@ public: inline void advance() noexcept { ++data; } inline void skip (int numSamples) noexcept { data += numSamples; } - inline float getAsFloatLE() const noexcept { return (float) ((1.0 / (1.0 + maxValue)) * (int16) ByteOrder::swapIfBigEndian (*data)); } + inline float getAsFloatLE() const noexcept { return (float) ((1.0 / (1.0 + maxValue)) * (int16) ByteOrder::swapIfBigEndian (*data)); } inline float getAsFloatBE() const noexcept { return (float) ((1.0 / (1.0 + maxValue)) * (int16) ByteOrder::swapIfLittleEndian (*data)); } - inline void setAsFloatLE (float newValue) noexcept { *data = ByteOrder::swapIfBigEndian ((uint16) jlimit ((int) -maxValue, (int) maxValue, roundToInt (newValue * (1.0 + maxValue)))); } + inline void setAsFloatLE (float newValue) noexcept { *data = ByteOrder::swapIfBigEndian ((uint16) jlimit ((int) -maxValue, (int) maxValue, roundToInt (newValue * (1.0 + maxValue)))); } inline void setAsFloatBE (float newValue) noexcept { *data = ByteOrder::swapIfLittleEndian ((uint16) jlimit ((int) -maxValue, (int) maxValue, roundToInt (newValue * (1.0 + maxValue)))); } - inline int32 getAsInt32LE() const noexcept { return (int32) (ByteOrder::swapIfBigEndian ((uint16) *data) << 16); } + inline int32 getAsInt32LE() const noexcept { return (int32) (ByteOrder::swapIfBigEndian ((uint16) *data) << 16); } inline int32 getAsInt32BE() const noexcept { return (int32) (ByteOrder::swapIfLittleEndian ((uint16) *data) << 16); } - inline void setAsInt32LE (int32 newValue) noexcept { *data = ByteOrder::swapIfBigEndian ((uint16) (newValue >> 16)); } + inline void setAsInt32LE (int32 newValue) noexcept { *data = ByteOrder::swapIfBigEndian ((uint16) (newValue >> 16)); } inline void setAsInt32BE (int32 newValue) noexcept { *data = ByteOrder::swapIfLittleEndian ((uint16) (newValue >> 16)); } inline void clear() noexcept { *data = 0; } inline void clearMultiple (int num) noexcept { zeromem (data, (size_t) (num * bytesPerSample)) ;} @@ -176,13 +176,13 @@ public: inline void advance() noexcept { data += 3; } inline void skip (int numSamples) noexcept { data += 3 * numSamples; } inline float getAsFloatLE() const noexcept { return (float) (ByteOrder::littleEndian24Bit (data) * (1.0 / (1.0 + maxValue))); } - inline float getAsFloatBE() const noexcept { return (float) (ByteOrder::bigEndian24Bit (data) * (1.0 / (1.0 + maxValue))); } + inline float getAsFloatBE() const noexcept { return (float) (ByteOrder::bigEndian24Bit (data) * (1.0 / (1.0 + maxValue))); } inline void setAsFloatLE (float newValue) noexcept { ByteOrder::littleEndian24BitToChars (jlimit ((int) -maxValue, (int) maxValue, roundToInt (newValue * (1.0 + maxValue))), data); } - inline void setAsFloatBE (float newValue) noexcept { ByteOrder::bigEndian24BitToChars (jlimit ((int) -maxValue, (int) maxValue, roundToInt (newValue * (1.0 + maxValue))), data); } - inline int32 getAsInt32LE() const noexcept { return (int32) ByteOrder::littleEndian24Bit (data) << 8; } - inline int32 getAsInt32BE() const noexcept { return (int32) ByteOrder::bigEndian24Bit (data) << 8; } + inline void setAsFloatBE (float newValue) noexcept { ByteOrder::bigEndian24BitToChars (jlimit ((int) -maxValue, (int) maxValue, roundToInt (newValue * (1.0 + maxValue))), data); } + inline int32 getAsInt32LE() const noexcept { return (int32) (((unsigned int) ByteOrder::littleEndian24Bit (data)) << 8); } + inline int32 getAsInt32BE() const noexcept { return (int32) (((unsigned int) ByteOrder::bigEndian24Bit (data)) << 8); } inline void setAsInt32LE (int32 newValue) noexcept { ByteOrder::littleEndian24BitToChars (newValue >> 8, data); } - inline void setAsInt32BE (int32 newValue) noexcept { ByteOrder::bigEndian24BitToChars (newValue >> 8, data); } + inline void setAsInt32BE (int32 newValue) noexcept { ByteOrder::bigEndian24BitToChars (newValue >> 8, data); } inline void clear() noexcept { data[0] = 0; data[1] = 0; data[2] = 0; } inline void clearMultiple (int num) noexcept { zeromem (data, (size_t) (num * bytesPerSample)) ;} template inline void copyFromLE (SourceType& source) noexcept { setAsInt32LE (source.getAsInt32()); } @@ -200,10 +200,10 @@ public: inline void advance() noexcept { ++data; } inline void skip (int numSamples) noexcept { data += numSamples; } - inline float getAsFloatLE() const noexcept { return (float) ((1.0 / (1.0 + maxValue)) * (int32) ByteOrder::swapIfBigEndian (*data)); } + inline float getAsFloatLE() const noexcept { return (float) ((1.0 / (1.0 + maxValue)) * (int32) ByteOrder::swapIfBigEndian (*data)); } inline float getAsFloatBE() const noexcept { return (float) ((1.0 / (1.0 + maxValue)) * (int32) ByteOrder::swapIfLittleEndian (*data)); } - inline void setAsFloatLE (float newValue) noexcept { *data = ByteOrder::swapIfBigEndian ((uint32) (maxValue * jlimit (-1.0, 1.0, (double) newValue))); } - inline void setAsFloatBE (float newValue) noexcept { *data = ByteOrder::swapIfLittleEndian ((uint32) (maxValue * jlimit (-1.0, 1.0, (double) newValue))); } + inline void setAsFloatLE (float newValue) noexcept { *data = ByteOrder::swapIfBigEndian ((uint32) (int32) (maxValue * jlimit (-1.0, 1.0, (double) newValue))); } + inline void setAsFloatBE (float newValue) noexcept { *data = ByteOrder::swapIfLittleEndian ((uint32) (int32) (maxValue * jlimit (-1.0, 1.0, (double) newValue))); } inline int32 getAsInt32LE() const noexcept { return (int32) ByteOrder::swapIfBigEndian (*data); } inline int32 getAsInt32BE() const noexcept { return (int32) ByteOrder::swapIfLittleEndian (*data); } inline void setAsInt32LE (int32 newValue) noexcept { *data = ByteOrder::swapIfBigEndian ((uint32) newValue); } diff --git a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp index be1d59f655..cbf6fb2554 100644 --- a/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp +++ b/modules/juce_audio_basics/buffers/juce_FloatVectorOperations.cpp @@ -1066,6 +1066,8 @@ public: ValueType* const data2 = buffer2; int* const int1 = buffer3; #else + // These tests deliberately operate on misaligned memory and will be flagged up by + // checks for undefined behavior! ValueType* const data1 = addBytesToPointer (buffer1.getData(), random.nextInt (16)); ValueType* const data2 = addBytesToPointer (buffer2.getData(), random.nextInt (16)); int* const int1 = addBytesToPointer (buffer3.getData(), random.nextInt (16)); diff --git a/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp b/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp index e68c8bd33c..9021d68142 100644 --- a/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp +++ b/modules/juce_audio_formats/codecs/juce_WavAudioFormat.cpp @@ -154,7 +154,7 @@ const char* const WavAudioFormat::tracktionLoopInfo = "tracktion loop info"; //============================================================================== namespace WavFileHelpers { - inline int chunkName (const char* const name) noexcept { return (int) ByteOrder::littleEndianInt (name); } + inline int chunkName (const char* const name) noexcept { return (int) ByteOrder::littleEndianInt (name[0], name[1], name[2], name[3]); } inline size_t roundUpSize (size_t sz) noexcept { return (sz + 3) & ~3u; } #if JUCE_MSVC diff --git a/modules/juce_core/maths/juce_Random.cpp b/modules/juce_core/maths/juce_Random.cpp index 5d83f718aa..9fa81369e4 100644 --- a/modules/juce_core/maths/juce_Random.cpp +++ b/modules/juce_core/maths/juce_Random.cpp @@ -64,7 +64,7 @@ Random& Random::getSystemRandom() noexcept //============================================================================== int Random::nextInt() noexcept { - seed = (seed * 0x5deece66dLL + 11) & 0xffffffffffffLL; + seed = (int64) (((((uint64) seed) * 0x5deece66dLL) + 11) & 0xffffffffffffLL); return (int) (seed >> 16); } @@ -82,7 +82,7 @@ int Random::nextInt (Range range) noexcept int64 Random::nextInt64() noexcept { - return (((int64) nextInt()) << 32) | (int64) (uint64) (uint32) nextInt(); + return (int64) ((((uint64) (unsigned int) nextInt()) << 32) | (uint64) (unsigned int) nextInt()); } bool Random::nextBool() noexcept diff --git a/modules/juce_core/memory/juce_ByteOrder.h b/modules/juce_core/memory/juce_ByteOrder.h index ac08b066e5..49c79c181a 100644 --- a/modules/juce_core/memory/juce_ByteOrder.h +++ b/modules/juce_core/memory/juce_ByteOrder.h @@ -32,7 +32,7 @@ class JUCE_API ByteOrder public: //============================================================================== /** Swaps the upper and lower bytes of a 16-bit integer. */ - static uint16 swap (uint16 value) noexcept; + JUCE_CONSTEXPR static uint16 swap (uint16 value) noexcept; /** Reverses the order of the 4 bytes in a 32-bit integer. */ static uint32 swap (uint32 value) noexcept; @@ -42,7 +42,7 @@ public: //============================================================================== /** Swaps the byte order of a 16-bit unsigned int if the CPU is big-endian */ - static uint16 swapIfBigEndian (uint16 value) noexcept; + JUCE_CONSTEXPR static uint16 swapIfBigEndian (uint16 value) noexcept; /** Swaps the byte order of a 32-bit unsigned int if the CPU is big-endian */ static uint32 swapIfBigEndian (uint32 value) noexcept; @@ -51,7 +51,7 @@ public: static uint64 swapIfBigEndian (uint64 value) noexcept; /** Swaps the byte order of a 16-bit signed int if the CPU is big-endian */ - static int16 swapIfBigEndian (int16 value) noexcept; + JUCE_CONSTEXPR static int16 swapIfBigEndian (int16 value) noexcept; /** Swaps the byte order of a 32-bit signed int if the CPU is big-endian */ static int32 swapIfBigEndian (int32 value) noexcept; @@ -66,7 +66,7 @@ public: static double swapIfBigEndian (double value) noexcept; /** Swaps the byte order of a 16-bit unsigned int if the CPU is little-endian */ - static uint16 swapIfLittleEndian (uint16 value) noexcept; + JUCE_CONSTEXPR static uint16 swapIfLittleEndian (uint16 value) noexcept; /** Swaps the byte order of a 32-bit unsigned int if the CPU is little-endian */ static uint32 swapIfLittleEndian (uint32 value) noexcept; @@ -75,7 +75,7 @@ public: static uint64 swapIfLittleEndian (uint64 value) noexcept; /** Swaps the byte order of a 16-bit signed int if the CPU is little-endian */ - static int16 swapIfLittleEndian (int16 value) noexcept; + JUCE_CONSTEXPR static int16 swapIfLittleEndian (int16 value) noexcept; /** Swaps the byte order of a 32-bit signed int if the CPU is little-endian */ static int32 swapIfLittleEndian (int32 value) noexcept; @@ -93,6 +93,9 @@ public: /** Turns 4 bytes into a little-endian integer. */ static uint32 littleEndianInt (const void* bytes) noexcept; + /** Turns 4 characters into a little-endian integer. */ + JUCE_CONSTEXPR static uint32 littleEndianInt (char c1, char c2, char c3, char c4) noexcept; + /** Turns 8 bytes into a little-endian integer. */ static uint64 littleEndianInt64 (const void* bytes) noexcept; @@ -123,7 +126,7 @@ public: //============================================================================== /** Returns true if the current CPU is big-endian. */ - static bool isBigEndian() noexcept; + JUCE_CONSTEXPR static bool isBigEndian() noexcept; private: ByteOrder() JUCE_DELETED_FUNCTION; @@ -137,7 +140,7 @@ private: #pragma intrinsic (_byteswap_ulong) #endif -inline uint16 ByteOrder::swap (uint16 n) noexcept +JUCE_CONSTEXPR inline uint16 ByteOrder::swap (uint16 n) noexcept { return static_cast ((n << 8) | (n >> 8)); } @@ -170,60 +173,63 @@ inline uint64 ByteOrder::swap (uint64 value) noexcept } #if JUCE_LITTLE_ENDIAN - inline uint16 ByteOrder::swapIfBigEndian (const uint16 v) noexcept { return v; } - inline uint32 ByteOrder::swapIfBigEndian (const uint32 v) noexcept { return v; } - inline uint64 ByteOrder::swapIfBigEndian (const uint64 v) noexcept { return v; } - inline int16 ByteOrder::swapIfBigEndian (const int16 v) noexcept { return v; } - inline int32 ByteOrder::swapIfBigEndian (const int32 v) noexcept { return v; } - inline int64 ByteOrder::swapIfBigEndian (const int64 v) noexcept { return v; } - inline float ByteOrder::swapIfBigEndian (const float v) noexcept { return v; } - inline double ByteOrder::swapIfBigEndian (const double v) noexcept { return v; } + JUCE_CONSTEXPR inline uint16 ByteOrder::swapIfBigEndian (const uint16 v) noexcept { return v; } + inline uint32 ByteOrder::swapIfBigEndian (const uint32 v) noexcept { return v; } + inline uint64 ByteOrder::swapIfBigEndian (const uint64 v) noexcept { return v; } + JUCE_CONSTEXPR inline int16 ByteOrder::swapIfBigEndian (const int16 v) noexcept { return v; } + inline int32 ByteOrder::swapIfBigEndian (const int32 v) noexcept { return v; } + inline int64 ByteOrder::swapIfBigEndian (const int64 v) noexcept { return v; } + inline float ByteOrder::swapIfBigEndian (const float v) noexcept { return v; } + inline double ByteOrder::swapIfBigEndian (const double v) noexcept { return v; } - inline uint16 ByteOrder::swapIfLittleEndian (const uint16 v) noexcept { return swap (v); } - inline uint32 ByteOrder::swapIfLittleEndian (const uint32 v) noexcept { return swap (v); } - inline uint64 ByteOrder::swapIfLittleEndian (const uint64 v) noexcept { return swap (v); } - inline int16 ByteOrder::swapIfLittleEndian (const int16 v) noexcept { return static_cast (swap (static_cast (v))); } - inline int32 ByteOrder::swapIfLittleEndian (const int32 v) noexcept { return static_cast (swap (static_cast (v))); } - inline int64 ByteOrder::swapIfLittleEndian (const int64 v) noexcept { return static_cast (swap (static_cast (v))); } -inline float ByteOrder::swapIfLittleEndian (const float v) noexcept { union { uint32 asUInt; float asFloat; } n; n.asFloat = v; n.asUInt = ByteOrder::swap (n.asUInt); return n.asFloat; } - inline double ByteOrder::swapIfLittleEndian (const double v) noexcept { union { uint64 asUInt; double asFloat; } n; n.asFloat = v; n.asUInt = ByteOrder::swap (n.asUInt); return n.asFloat; } + JUCE_CONSTEXPR inline uint16 ByteOrder::swapIfLittleEndian (const uint16 v) noexcept { return swap (v); } + inline uint32 ByteOrder::swapIfLittleEndian (const uint32 v) noexcept { return swap (v); } + inline uint64 ByteOrder::swapIfLittleEndian (const uint64 v) noexcept { return swap (v); } + JUCE_CONSTEXPR inline int16 ByteOrder::swapIfLittleEndian (const int16 v) noexcept { return static_cast (swap (static_cast (v))); } + inline int32 ByteOrder::swapIfLittleEndian (const int32 v) noexcept { return static_cast (swap (static_cast (v))); } + inline int64 ByteOrder::swapIfLittleEndian (const int64 v) noexcept { return static_cast (swap (static_cast (v))); } + inline float ByteOrder::swapIfLittleEndian (const float v) noexcept { union { uint32 asUInt; float asFloat; } n; n.asFloat = v; n.asUInt = ByteOrder::swap (n.asUInt); return n.asFloat; } + inline double ByteOrder::swapIfLittleEndian (const double v) noexcept { union { uint64 asUInt; double asFloat; } n; n.asFloat = v; n.asUInt = ByteOrder::swap (n.asUInt); return n.asFloat; } - inline uint32 ByteOrder::littleEndianInt (const void* const bytes) noexcept { return *static_cast (bytes); } - inline uint64 ByteOrder::littleEndianInt64 (const void* const bytes) noexcept { return *static_cast (bytes); } - inline uint16 ByteOrder::littleEndianShort (const void* const bytes) noexcept { return *static_cast (bytes); } - inline uint32 ByteOrder::bigEndianInt (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } - inline uint64 ByteOrder::bigEndianInt64 (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } - inline uint16 ByteOrder::bigEndianShort (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } - inline bool ByteOrder::isBigEndian() noexcept { return false; } + inline uint32 ByteOrder::littleEndianInt (const void* const bytes) noexcept { return *static_cast (bytes); } + JUCE_CONSTEXPR inline uint32 ByteOrder::littleEndianInt (char c1, char c2, char c3, char c4) noexcept { return (((uint32) c4) << 24) + (((uint32) c3) << 16) + (((uint32) c2) << 8) + (uint32) c1; } + + inline uint64 ByteOrder::littleEndianInt64 (const void* const bytes) noexcept { return *static_cast (bytes); } + inline uint16 ByteOrder::littleEndianShort (const void* const bytes) noexcept { return *static_cast (bytes); } + inline uint32 ByteOrder::bigEndianInt (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } + inline uint64 ByteOrder::bigEndianInt64 (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } + inline uint16 ByteOrder::bigEndianShort (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } + JUCE_CONSTEXPR inline bool ByteOrder::isBigEndian() noexcept { return false; } #else - inline uint16 ByteOrder::swapIfBigEndian (const uint16 v) noexcept { return swap (v); } - inline uint32 ByteOrder::swapIfBigEndian (const uint32 v) noexcept { return swap (v); } - inline uint64 ByteOrder::swapIfBigEndian (const uint64 v) noexcept { return swap (v); } - inline int16 ByteOrder::swapIfBigEndian (const int16 v) noexcept { return static_cast (swap (static_cast (v))); } - inline int32 ByteOrder::swapIfBigEndian (const int32 v) noexcept { return static_cast (swap (static_cast (v))); } - inline int64 ByteOrder::swapIfBigEndian (const int64 v) noexcept { return static_cast (swap (static_cast (v))); } - inline float ByteOrder::swapIfBigEndian (const float v) noexcept { union { uint32 asUInt; float asFloat; } n; n.asFloat = v; n.asUInt = ByteOrder::swap (n.asUInt); return n.asFloat; } - inline double ByteOrder::swapIfBigEndian (const double v) noexcept { union { uint64 asUInt; double asFloat; } n; n.asFloat = v; n.asUInt = ByteOrder::swap (n.asUInt); return n.asFloat; } + JUCE_CONSTEXPR inline uint16 ByteOrder::swapIfBigEndian (const uint16 v) noexcept { return swap (v); } + inline uint32 ByteOrder::swapIfBigEndian (const uint32 v) noexcept { return swap (v); } + inline uint64 ByteOrder::swapIfBigEndian (const uint64 v) noexcept { return swap (v); } + JUCE_CONSTEXPR inline int16 ByteOrder::swapIfBigEndian (const int16 v) noexcept { return static_cast (swap (static_cast (v))); } + inline int32 ByteOrder::swapIfBigEndian (const int32 v) noexcept { return static_cast (swap (static_cast (v))); } + inline int64 ByteOrder::swapIfBigEndian (const int64 v) noexcept { return static_cast (swap (static_cast (v))); } + inline float ByteOrder::swapIfBigEndian (const float v) noexcept { union { uint32 asUInt; float asFloat; } n; n.asFloat = v; n.asUInt = ByteOrder::swap (n.asUInt); return n.asFloat; } + inline double ByteOrder::swapIfBigEndian (const double v) noexcept { union { uint64 asUInt; double asFloat; } n; n.asFloat = v; n.asUInt = ByteOrder::swap (n.asUInt); return n.asFloat; } - inline uint16 ByteOrder::swapIfLittleEndian (const uint16 v) noexcept { return v; } - inline uint32 ByteOrder::swapIfLittleEndian (const uint32 v) noexcept { return v; } - inline uint64 ByteOrder::swapIfLittleEndian (const uint64 v) noexcept { return v; } - inline int16 ByteOrder::swapIfLittleEndian (const int16 v) noexcept { return v; } - inline int32 ByteOrder::swapIfLittleEndian (const int32 v) noexcept { return v; } - inline int64 ByteOrder::swapIfLittleEndian (const int64 v) noexcept { return v; } - inline float ByteOrder::swapIfLittleEndian (const float v) noexcept { return v; } - inline double ByteOrder::swapIfLittleEndian (const double v) noexcept { return v; } + JUCE_CONSTEXPR inline uint16 ByteOrder::swapIfLittleEndian (const uint16 v) noexcept { return v; } + inline uint32 ByteOrder::swapIfLittleEndian (const uint32 v) noexcept { return v; } + inline uint64 ByteOrder::swapIfLittleEndian (const uint64 v) noexcept { return v; } + JUCE_CONSTEXPR inline int16 ByteOrder::swapIfLittleEndian (const int16 v) noexcept { return v; } + inline int32 ByteOrder::swapIfLittleEndian (const int32 v) noexcept { return v; } + inline int64 ByteOrder::swapIfLittleEndian (const int64 v) noexcept { return v; } + inline float ByteOrder::swapIfLittleEndian (const float v) noexcept { return v; } + inline double ByteOrder::swapIfLittleEndian (const double v) noexcept { return v; } - inline uint32 ByteOrder::littleEndianInt (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } - inline uint64 ByteOrder::littleEndianInt64 (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } - inline uint16 ByteOrder::littleEndianShort (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } - inline uint32 ByteOrder::bigEndianInt (const void* const bytes) noexcept { return *static_cast (bytes); } - inline uint64 ByteOrder::bigEndianInt64 (const void* const bytes) noexcept { return *static_cast (bytes); } - inline uint16 ByteOrder::bigEndianShort (const void* const bytes) noexcept { return *static_cast (bytes); } - inline bool ByteOrder::isBigEndian() noexcept { return true; } + inline uint32 ByteOrder::littleEndianInt (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } + JUCE_CONSTEXPR inline uint32 ByteOrder::littleEndianInt (char c1, char c2, char c3, char c4) noexcept { return (((uint32) c1) << 24) + (((uint32) c2) << 16) + (((uint32) c3) << 8) + (uint32) c4; } + inline uint64 ByteOrder::littleEndianInt64 (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } + inline uint16 ByteOrder::littleEndianShort (const void* const bytes) noexcept { return swap (*static_cast (bytes)); } + inline uint32 ByteOrder::bigEndianInt (const void* const bytes) noexcept { return *static_cast (bytes); } + inline uint64 ByteOrder::bigEndianInt64 (const void* const bytes) noexcept { return *static_cast (bytes); } + inline uint16 ByteOrder::bigEndianShort (const void* const bytes) noexcept { return *static_cast (bytes); } + JUCE_CONSTEXPR inline bool ByteOrder::isBigEndian() noexcept { return true; } #endif -inline int ByteOrder::littleEndian24Bit (const void* const bytes) noexcept { return (((int) static_cast (bytes)[2]) << 16) | (((int) static_cast (bytes)[1]) << 8) | ((int) static_cast (bytes)[0]); } -inline int ByteOrder::bigEndian24Bit (const void* const bytes) noexcept { return (((int) static_cast (bytes)[0]) << 16) | (((int) static_cast (bytes)[1]) << 8) | ((int) static_cast (bytes)[2]); } -inline void ByteOrder::littleEndian24BitToChars (const int value, void* const destBytes) noexcept { static_cast (destBytes)[0] = (uint8) value; static_cast (destBytes)[1] = (uint8) (value >> 8); static_cast (destBytes)[2] = (uint8) (value >> 16); } -inline void ByteOrder::bigEndian24BitToChars (const int value, void* const destBytes) noexcept { static_cast (destBytes)[0] = (uint8) (value >> 16); static_cast (destBytes)[1] = (uint8) (value >> 8); static_cast (destBytes)[2] = (uint8) value; } +inline int ByteOrder::littleEndian24Bit (const void* const bytes) noexcept { return (int) ((((unsigned int) static_cast (bytes)[2]) << 16) | (((unsigned int) static_cast (bytes)[1]) << 8) | ((unsigned int) static_cast (bytes)[0])); } +inline int ByteOrder::bigEndian24Bit (const void* const bytes) noexcept { return (int) ((((unsigned int) static_cast (bytes)[0]) << 16) | (((unsigned int) static_cast (bytes)[1]) << 8) | ((unsigned int) static_cast (bytes)[2])); } +inline void ByteOrder::littleEndian24BitToChars (const int value, void* const destBytes) noexcept { static_cast (destBytes)[0] = (uint8) value; static_cast (destBytes)[1] = (uint8) (value >> 8); static_cast (destBytes)[2] = (uint8) (value >> 16); } +inline void ByteOrder::bigEndian24BitToChars (const int value, void* const destBytes) noexcept { static_cast (destBytes)[0] = (uint8) (value >> 16); static_cast (destBytes)[1] = (uint8) (value >> 8); static_cast (destBytes)[2] = (uint8) value; } diff --git a/modules/juce_core/text/juce_CharPointer_UTF8.h b/modules/juce_core/text/juce_CharPointer_UTF8.h index 1fe844e095..639b5c2d1e 100644 --- a/modules/juce_core/text/juce_CharPointer_UTF8.h +++ b/modules/juce_core/text/juce_CharPointer_UTF8.h @@ -470,12 +470,10 @@ public: /** Parses this string as a 64-bit integer. */ int64 getIntValue64() const noexcept { - #if JUCE_LINUX || JUCE_ANDROID || JUCE_MINGW - return atoll (data); - #elif JUCE_WINDOWS + #if JUCE_WINDOWS return _atoi64 (data); #else - return CharacterFunctions::getIntValue (*this); + return atoll (data); #endif } diff --git a/modules/juce_core/text/juce_CharacterFunctions.h b/modules/juce_core/text/juce_CharacterFunctions.h index 571a36c685..a0629b3448 100644 --- a/modules/juce_core/text/juce_CharacterFunctions.h +++ b/modules/juce_core/text/juce_CharacterFunctions.h @@ -243,7 +243,9 @@ public: template static IntType getIntValue (const CharPointerType text) noexcept { - IntType v = 0; + typedef typename std::make_unsigned::type UIntType; + + UIntType v = 0; auto s = text.findEndOfWhitespace(); const bool isNeg = *s == '-'; @@ -255,12 +257,12 @@ public: auto c = s.getAndAdvance(); if (c >= '0' && c <= '9') - v = v * 10 + (IntType) (c - '0'); + v = v * 10 + (UIntType) (c - '0'); else break; } - return isNeg ? -v : v; + return isNeg ? - (IntType) v : (IntType) v; } template diff --git a/modules/juce_core/text/juce_String.cpp b/modules/juce_core/text/juce_String.cpp index ef1a2844cc..f1598f983d 100644 --- a/modules/juce_core/text/juce_String.cpp +++ b/modules/juce_core/text/juce_String.cpp @@ -211,7 +211,7 @@ private: { // (Can't use offsetof() here because of warnings about this not being a POD) return reinterpret_cast (reinterpret_cast (text.getAddress()) - - (reinterpret_cast (reinterpret_cast (1)->text) - 1)); + - (reinterpret_cast (reinterpret_cast (128)->text) - 128)); } void compileTimeChecks() diff --git a/modules/juce_cryptography/encryption/juce_BlowFish.cpp b/modules/juce_cryptography/encryption/juce_BlowFish.cpp index cc16b5c9bc..7d2f7358f4 100644 --- a/modules/juce_cryptography/encryption/juce_BlowFish.cpp +++ b/modules/juce_cryptography/encryption/juce_BlowFish.cpp @@ -450,13 +450,15 @@ public: encryptDecryptTest (bf, data.getData(), data.getSize() - 8, data.getSize()); encryptDecryptTest (bf, data.getData(), 0, 8); + { + // Test unaligned data encryption/decryption. This will be flagged up by a check for + // undefined behaviour! + const uintptr_t nudge = static_cast (random.nextInt (sizeof(void*) - 1)); + void* unalignedData = (void*) (reinterpret_cast (data.getData()) + nudge); + size_t newSize = data.getSize() - nudge; - // test unaligned data encryption/decryption - const uintptr_t nudge = static_cast (random.nextInt (sizeof(void*) - 1)); - void* unalignedData = (void*) (reinterpret_cast (data.getData()) + nudge); - size_t newSize = data.getSize() - nudge; - - encryptDecryptTest (bf, unalignedData, newSize - 8, newSize); + encryptDecryptTest (bf, unalignedData, newSize - 8, newSize); + } } } }; diff --git a/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp b/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp index 812b2b7a41..666710f865 100644 --- a/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp +++ b/modules/juce_data_structures/app_properties/juce_PropertiesFile.cpp @@ -26,13 +26,13 @@ namespace PropertyFileConstants { - static const int magicNumber = (int) ByteOrder::littleEndianInt ("PROP"); - static const int magicNumberCompressed = (int) ByteOrder::littleEndianInt ("CPRP"); + JUCE_CONSTEXPR static const int magicNumber = (int) ByteOrder::littleEndianInt ('P', 'R', 'O', 'P'); + JUCE_CONSTEXPR static const int magicNumberCompressed = (int) ByteOrder::littleEndianInt ('C', 'P', 'R', 'P'); - static const char* const fileTag = "PROPERTIES"; - static const char* const valueTag = "VALUE"; - static const char* const nameAttribute = "name"; - static const char* const valueAttribute = "val"; + JUCE_CONSTEXPR static const char* const fileTag = "PROPERTIES"; + JUCE_CONSTEXPR static const char* const valueTag = "VALUE"; + JUCE_CONSTEXPR static const char* const nameAttribute = "name"; + JUCE_CONSTEXPR static const char* const valueAttribute = "val"; } //============================================================================== diff --git a/modules/juce_dsp/processors/juce_Oversampling.cpp b/modules/juce_dsp/processors/juce_Oversampling.cpp index c5d2a570e2..5748ec272d 100644 --- a/modules/juce_dsp/processors/juce_Oversampling.cpp +++ b/modules/juce_dsp/processors/juce_Oversampling.cpp @@ -492,7 +492,7 @@ Oversampling::Oversampling (size_t newNumChannels, size_t newFactor, { jassert (newFactor >= 0 && newFactor <= 4 && newNumChannels > 0); - factorOversampling = 1 << newFactor; + factorOversampling = (size_t) 1 << newFactor; isMaximumQuality = newMaxQuality; type = newType; numChannels = newNumChannels; @@ -543,7 +543,7 @@ template SampleType Oversampling::getLatencyInSamples() noexcept { auto latency = static_cast (0); - auto order = 1; + size_t order = 1; for (size_t n = 0; n < numStages; n++) {