diff options
-rw-r--r-- | framework/src/errors.h | 34 |
1 files changed, 32 insertions, 2 deletions
diff --git a/framework/src/errors.h b/framework/src/errors.h index ec5bed7b..d95272da 100644 --- a/framework/src/errors.h +++ b/framework/src/errors.h | |||
@@ -1,3 +1,21 @@ | |||
1 | /* | ||
2 | Copyright (c) 2018 Christian Mollekopf <mollekopf@kolabsys.com> | ||
3 | |||
4 | This library is free software; you can redistribute it and/or modify it | ||
5 | under the terms of the GNU Library General Public License as published by | ||
6 | the Free Software Foundation; either version 2 of the License, or (at your | ||
7 | option) any later version. | ||
8 | |||
9 | This library is distributed in the hope that it will be useful, but WITHOUT | ||
10 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
11 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public | ||
12 | License for more details. | ||
13 | |||
14 | You should have received a copy of the GNU Library General Public License | ||
15 | along with this library; see the file COPYING.LIB. If not, write to the | ||
16 | Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA | ||
17 | 02110-1301, USA. | ||
18 | */ | ||
1 | #pragma once | 19 | #pragma once |
2 | 20 | ||
3 | #include <memory> | 21 | #include <memory> |
@@ -92,6 +110,19 @@ protected: | |||
92 | { | 110 | { |
93 | // This is a constructor, you have to construct object, not assign them | 111 | // This is a constructor, you have to construct object, not assign them |
94 | // (hence the placement new) | 112 | // (hence the placement new) |
113 | // | ||
114 | // Here's the problem: | ||
115 | // | ||
116 | // Object that are part of a union are not initialized (which is | ||
117 | // normal). If we replaced the placement new by a line like this: | ||
118 | // | ||
119 | // ``` | ||
120 | // mValue = other.mValue; | ||
121 | // ``` | ||
122 | // | ||
123 | // If overloaded, this will call `mValue.operator=(other.mValue);`, but | ||
124 | // since we're in the constructor, mValue is not initialized. This can | ||
125 | // cause big issues if the Type is not trivially (move) assignable. | ||
95 | if (mIsValue) { | 126 | if (mIsValue) { |
96 | new (std::addressof(mValue)) Type(other.mValue); | 127 | new (std::addressof(mValue)) Type(other.mValue); |
97 | } else { | 128 | } else { |
@@ -101,8 +132,7 @@ protected: | |||
101 | 132 | ||
102 | StorageBase(StorageBase &&other) : mIsValue(other.mIsValue) | 133 | StorageBase(StorageBase &&other) : mIsValue(other.mIsValue) |
103 | { | 134 | { |
104 | // This is a constructor, you have to construct object, not assign them | 135 | // If you're thinking WTF, see the comment in the copy constructor above. |
105 | // (hence the placement new) | ||
106 | if (mIsValue) { | 136 | if (mIsValue) { |
107 | new (std::addressof(mValue)) Type(std::move(other.mValue)); | 137 | new (std::addressof(mValue)) Type(std::move(other.mValue)); |
108 | } else { | 138 | } else { |