aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/connection.cpp2
-rw-r--r--lib/e2ee/qolmmessage.cpp4
-rw-r--r--lib/uri.cpp2
-rw-r--r--lib/util.h16
4 files changed, 21 insertions, 3 deletions
diff --git a/lib/connection.cpp b/lib/connection.cpp
index d99ab64d..a969b3b9 100644
--- a/lib/connection.cpp
+++ b/lib/connection.cpp
@@ -2065,7 +2065,7 @@ void Connection::Private::loadOutdatedUserDevices()
continue;
}
}
- deviceKeys[user][device.deviceId] = device;
+ deviceKeys[user][device.deviceId] = SLICE(device, DeviceKeys);
}
outdatedUsers -= user;
}
diff --git a/lib/e2ee/qolmmessage.cpp b/lib/e2ee/qolmmessage.cpp
index 81b166b0..f9b4a5c2 100644
--- a/lib/e2ee/qolmmessage.cpp
+++ b/lib/e2ee/qolmmessage.cpp
@@ -4,6 +4,8 @@
#include "qolmmessage.h"
+#include "util.h"
+
using namespace Quotient;
QOlmMessage::QOlmMessage(QByteArray ciphertext, QOlmMessage::Type type)
@@ -26,7 +28,7 @@ QOlmMessage::Type QOlmMessage::type() const
QByteArray QOlmMessage::toCiphertext() const
{
- return QByteArray(*this);
+ return SLICE(*this, QByteArray);
}
QOlmMessage QOlmMessage::fromCiphertext(const QByteArray &ciphertext)
diff --git a/lib/uri.cpp b/lib/uri.cpp
index 6b7d1d20..91751df0 100644
--- a/lib/uri.cpp
+++ b/lib/uri.cpp
@@ -171,7 +171,7 @@ QUrl Uri::toUrl(UriForm form) const
return {};
if (form == CanonicalUri || type() == NonMatrix)
- return *this; // NOLINT(cppcoreguidelines-slicing): It's intentional
+ return SLICE(*this, QUrl);
QUrl url;
url.setScheme("https");
diff --git a/lib/util.h b/lib/util.h
index 753eb1ea..b14e1648 100644
--- a/lib/util.h
+++ b/lib/util.h
@@ -37,6 +37,22 @@ static_assert(false, "Use Q_DISABLE_MOVE instead; Quotient enables it across all
QT_WARNING_POP
#endif
+/// \brief Copy an object with slicing
+///
+/// Unintended slicing is bad, which why there's a C++ Core Guideline that
+/// basically says "don't slice, or if you do, make it explicit". Sonar and
+/// clang-tidy have warnings matching this guideline; unfortunately, those
+/// warnings trigger even when you have a dedicated method (as the guideline
+/// recommends) that makes a slicing copy.
+///
+/// This macro is meant for cases when slicing is intended: the static cast
+/// silences the static analysis warning, and the macro appearance itself makes
+/// it very clear that slicing is wanted here. It is made as a macro
+/// (not as a function template) to support the case of private inheritance
+/// in which a function template would not be able to cast to the private base
+/// (see Uri::toUrl() for an example of just that situation).
+#define SLICE(Object, ToType) ToType{static_cast<const ToType&>(Object)}
+
namespace Quotient {
/// An equivalent of std::hash for QTypes to enable std::unordered_map<QType, ...>
template <typename T>