diff options
author | 2017-10-26 14:51:52 -0700 | |
---|---|---|
committer | 2017-10-27 15:06:23 -0700 | |
commit | dfabcc50f13f27201fd9c0ab0def187ef5945fda (patch) | |
tree | eee8862eebf83d94cf8fb81042666732390933aa /runtime/base/bit_struct.h | |
parent | 2875173c75049777e6b63dbc9739846dd8f7d085 (diff) |
base: Fix bitstruct bug with assigning fields
Given a BitStruct 'foo', where bar was a BitStructField, assignment was
broken because it was using the C++ default behavior (copy the entire
word).
foo.bar = other_foo.bar
This will now correctly use BitFieldInsert to update the 'bar' bitfield.
Change-Id: I1464462ffd4df22ad14a2e43a34f74d75ac2809a
Diffstat (limited to 'runtime/base/bit_struct.h')
-rw-r--r-- | runtime/base/bit_struct.h | 18 |
1 files changed, 17 insertions, 1 deletions
diff --git a/runtime/base/bit_struct.h b/runtime/base/bit_struct.h index 1f86ee1917..16b555e1c6 100644 --- a/runtime/base/bit_struct.h +++ b/runtime/base/bit_struct.h @@ -130,6 +130,18 @@ struct BitStructField { return kBitWidth; } + BitStructField& operator=(const BitStructField& other) { + // Warning. The default operator= will overwrite the entire storage! + return *this = static_cast<T>(other); + } + + BitStructField(const BitStructField& other) { + Assign(*this, static_cast<T>(other)); + } + + BitStructField() = default; + ~BitStructField() = default; + protected: template <typename T2> T2& Assign(T2& what, T value) { @@ -265,7 +277,11 @@ using BitStructUint = #define BITSTRUCT_DEFINE_START(name, bitwidth) \ union name { \ art::detail::DefineBitStructSize<(bitwidth)> _; \ - static constexpr size_t BitStructSizeOf() { return (bitwidth); } + static constexpr size_t BitStructSizeOf() { return (bitwidth); } \ + name& operator=(const name& other) { _ = other._; return *this; } \ + name(const name& other) : _(other._) {} \ + name() = default; \ + ~name() = default; // End the definition of a bitstruct, and insert a sanity check // to ensure that the bitstruct did not exceed the specified size. |