From e94dd497e760dcc72d048989f7d5d1c7e5aab862 Mon Sep 17 00:00:00 2001 From: Andreas Stöckel Date: Fri, 20 Feb 2015 05:00:12 +0100 Subject: fixed aliasing issue in VariantMetadata --- src/core/common/Variant.cpp | 22 ++++++++-------- src/core/common/Variant.hpp | 64 +++++++++++++++++++++++++++------------------ 2 files changed, 49 insertions(+), 37 deletions(-) (limited to 'src') diff --git a/src/core/common/Variant.cpp b/src/core/common/Variant.cpp index 836fed3..280cba5 100644 --- a/src/core/common/Variant.cpp +++ b/src/core/common/Variant.cpp @@ -34,20 +34,20 @@ namespace ousia { bool VariantMetadata::hasLocation() const { - return locationSourceId != InvalidSourceId; + return data.locationSourceId != InvalidSourceId; } SourceLocation VariantMetadata::getLocation() const { - if (locationOffset == InvalidLocationOffset) { - return SourceLocation(locationSourceId); + if (data.locationOffset == InvalidLocationOffset) { + return SourceLocation(data.locationSourceId); } - if (locationLength == InvalidLocationLength) { - return SourceLocation(locationSourceId, locationOffset); + if (data.locationLength == InvalidLocationLength) { + return SourceLocation(data.locationSourceId, data.locationOffset); } - return SourceLocation(locationSourceId, locationOffset, - static_cast(locationOffset) + - static_cast(locationLength)); + return SourceLocation(data.locationSourceId, data.locationOffset, + static_cast(data.locationOffset) + + static_cast(data.locationLength)); } void VariantMetadata::setLocation(const SourceLocation &location) @@ -58,11 +58,11 @@ void VariantMetadata::setLocation(const SourceLocation &location) const size_t length = location.getLength(); // Copy the location, mark values that cannot be stored as invalid - locationSourceId = + data.locationSourceId = sourceId < InvalidLocationSourceId ? sourceId : InvalidLocationSourceId; - locationOffset = + data.locationOffset = offset < InvalidLocationOffset ? offset : InvalidLocationOffset; - locationLength = + data.locationLength = length < InvalidLocationLength ? length : InvalidLocationLength; } diff --git a/src/core/common/Variant.hpp b/src/core/common/Variant.hpp index ddd17d7..4cdc94f 100644 --- a/src/core/common/Variant.hpp +++ b/src/core/common/Variant.hpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -75,26 +76,37 @@ enum class VariantType : uint8_t { * was found in 8 Bytes. */ struct VariantMetadata { - /** - * Field used to store the type of a Variant (4 Bit, space for 16 objects). - */ - uint8_t variantType : 4; - - /** - * Field used to store the location at which the Variant was found (30 Bit). - */ - uint32_t locationOffset : 30; // Enough for 1GB - - /** - * Field used to store the length of the value from which the variant was - * parsed (14 Bit). - */ - uint16_t locationLength : 14; // 16.000 Bytes of context + union { + struct { + /** + * Field used to store the type of a Variant (4 Bit, space for 16 + * objects). + */ + uint8_t variantType : 4; + + /** + * Field used to store the location at which the Variant was found + * (30 Bit). + */ + uint32_t locationOffset : 30; // Enough for 1GB + + /** + * Field used to store the length of the value from which the + * variant was parsed (14 Bit). + */ + uint16_t locationLength : 14; // 16.000 Bytes of context + + /** + * Unique id of the file from which the variant was parsed. + */ + uint16_t locationSourceId : 16; // 65.000 Source files + } data; - /** - * Unique id of the file from which the variant was parsed. - */ - uint16_t locationSourceId : 16; // 65.000 Source files + /** + * The metadata as 64 Bit value. + */ + uint64_t intData; + }; /** * Maximum byte offset for locations that can be stored. @@ -115,10 +127,7 @@ struct VariantMetadata { * Default constructor. Sets the type to nullptr and all other fields to * invalid. */ - VariantMetadata() - { - *(reinterpret_cast(this)) = 0xFFFFFFFFFFFFFFFFull; - } + VariantMetadata() { intData = std::numeric_limits::max(); } /** * Sets the type to the given type and all other fields to invalid. @@ -127,7 +136,7 @@ struct VariantMetadata { */ VariantMetadata(VariantType type) : VariantMetadata() { - variantType = static_cast(type); + data.variantType = static_cast(type); } /** @@ -137,7 +146,7 @@ struct VariantMetadata { */ VariantType getType() const { - return static_cast(variantType); + return static_cast(data.variantType); } /** @@ -145,7 +154,10 @@ struct VariantMetadata { * * @param type is the variant type that should be stored. */ - void setType(VariantType type) { variantType = static_cast(type); } + void setType(VariantType type) + { + data.variantType = static_cast(type); + } /** * Returns true if the stored source id is not invalid. -- cgit v1.2.3