1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 04:32:44 +01:00

[ADT] Defend against getting slightly wrong template arguments passed

into CRTP base classes.

This can sometimes happen and not cause an immediate failure when the
derived class is, itself, a template. You can end up essentially calling
methods on the wrong derived type but a type where many things will
appear to "work".

To fail fast and with a clear error message we can use a static_assert,
but we have to stash that static_assert inside a method body or nested
type that won't need to be completed while building the base class. I've
tried to pick a reasonably small number of places that seemed like
reliably places for this to be instantiated.

llvm-svn: 294271
This commit is contained in:
Chandler Carruth 2017-02-07 03:15:12 +00:00
parent d347862ffe
commit c69a2c11a3
2 changed files with 10 additions and 1 deletions

View File

@ -389,6 +389,8 @@ protected:
return KeyInfoT::getHashValue(Val);
}
static const KeyT getEmptyKey() {
static_assert(std::is_base_of<DenseMapBase, DerivedT>::value,
"Must pass the derived type to this template!");
return KeyInfoT::getEmptyKey();
}
static const KeyT getTombstoneKey() {

View File

@ -91,6 +91,8 @@ protected:
public:
DerivedT operator+(DifferenceTypeT n) const {
static_assert(std::is_base_of<iterator_facade_base, DerivedT>::value,
"Must pass the derived type to this template!");
static_assert(
IsRandomAccess,
"The '+' operator is only defined for random access iterators.");
@ -114,6 +116,8 @@ public:
}
DerivedT &operator++() {
static_assert(std::is_base_of<iterator_facade_base, DerivedT>::value,
"Must pass the derived type to this template!");
return static_cast<DerivedT *>(this)->operator+=(1);
}
DerivedT operator++(int) {
@ -202,7 +206,10 @@ protected:
iterator_adaptor_base() = default;
explicit iterator_adaptor_base(WrappedIteratorT u) : I(std::move(u)) {}
explicit iterator_adaptor_base(WrappedIteratorT u) : I(std::move(u)) {
static_assert(std::is_base_of<iterator_adaptor_base, DerivedT>::value,
"Must pass the derived type to this template!");
}
const WrappedIteratorT &wrapped() const { return I; }