Skip to content

Commit aba2383

Browse files
Ensure that the generic NumericAttributeTraits is only used for types it supports. (#36459)
It turned out to be easy to use it for some struct type and get weird behavior; we should not allow that to compile.
1 parent b825bb3 commit aba2383

File tree

2 files changed

+9
-3
lines changed

2 files changed

+9
-3
lines changed

src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848

4949
namespace chip {
5050
namespace app {
51+
5152
namespace {
5253

5354
using namespace chip::app::Compatibility::Internal;

src/app/util/attribute-storage-null-handling.h

+8-3
Original file line numberDiff line numberDiff line change
@@ -60,22 +60,27 @@ struct NumericAttributeTraits
6060
static constexpr WorkingType StorageToWorking(StorageType storageValue) { return storageValue; }
6161

6262
private:
63+
// Ensure that this generic NumericAttributeTraits implementation is being used for some type for which it
64+
// actually works.
65+
static_assert(std::is_floating_point_v<T> || std::is_integral_v<T> || std::is_enum_v<T>,
66+
"NumericAttributeTraits specialization needed for this type");
67+
6368
// We need to make sure we never look like we are assigning NaN to an
6469
// integer, even in a not-reached branch. Without "if constexpr", the best
6570
// we can do is these functions using enable_if.
66-
template <typename U = T, typename std::enable_if_t<std::is_floating_point<U>::value, int> = 0>
71+
template <typename U = T, typename std::enable_if_t<std::is_floating_point_v<U>, int> = 0>
6772
static constexpr StorageType GetNullValue()
6873
{
6974
return std::numeric_limits<T>::quiet_NaN();
7075
}
7176

72-
template <typename U = T, typename std::enable_if_t<std::is_integral<U>::value, int> = 0>
77+
template <typename U = T, typename std::enable_if_t<std::is_integral_v<U>, int> = 0>
7378
static constexpr StorageType GetNullValue()
7479
{
7580
return std::is_signed<T>::value ? std::numeric_limits<T>::min() : std::numeric_limits<T>::max();
7681
}
7782

78-
template <typename U = T, typename std::enable_if_t<std::is_enum<U>::value, int> = 0>
83+
template <typename U = T, typename std::enable_if_t<std::is_enum_v<U>, int> = 0>
7984
static constexpr StorageType GetNullValue()
8085
{
8186
static_assert(!std::is_signed<std::underlying_type_t<T>>::value, "Enums must be unsigned");

0 commit comments

Comments
 (0)